账户
0x36...178f
0x36...178F

0x36...178F

$500
此合同的源代码已经过验证!
合同元数据
编译器
0.8.25+commit.b61c2a91
语言
Solidity
合同源代码
文件 1 的 1:RebalanceHelper.sol
// SPDX-License-Identifier: BSUL-1.1
pragma solidity ^0.8.19;

interface NotionalProxy {
    function rebalance(uint16 currencyId) external;

    function checkRebalance() external view returns (uint16[] memory currencyId);
}

contract RebalanceHelper {
    event RebalancingFailed(uint16 currencyId, bytes reason);
    event RebalancingSucceeded(uint16 currencyId);

    error CurrencyIdsLengthCannotBeZero();
    error CurrencyIdsNeedToBeSorted();
    error Unauthorized();

    address public constant RELAYER_ADDRESS = 0x745915418D8B70f39ce9e61A965cBB0C87f9f7Ed; 
    uint256 public constant DELAY_AFTER_FAILURE = 10 minutes;
    NotionalProxy public immutable NOTIONAL;

    mapping(uint16 currencyId => uint32 lastFailedRebalanceTimestamp) public failedRebalanceMap;

    constructor(NotionalProxy notionalAddress) {
        NOTIONAL = notionalAddress;
    }

    function checkAndRebalance() external {
        uint16[] memory currencyIdsToProcess = checkRebalance();
        if (currencyIdsToProcess.length > 0) {
            rebalanceCurrencyIds(currencyIdsToProcess);
        }
    }


    function rebalanceCurrencyIds(uint16[] memory currencyIds) public {
        if (currencyIds.length == 0) {
            revert CurrencyIdsLengthCannotBeZero();
        }
        if (msg.sender != RELAYER_ADDRESS) {
            revert Unauthorized();
        }

        for (uint256 i = 0; i < currencyIds.length; i++) {
            uint16 currencyId = currencyIds[i];
            // ensure currency ids are unique and sorted
            if (i != 0 && currencyIds[i - 1] >= currencyId) {
                revert CurrencyIdsNeedToBeSorted();
            }

            // Rebalance each of the currencies provided.
            try NOTIONAL.rebalance(currencyId) {
                emit RebalancingSucceeded(currencyId);
            } catch (bytes memory reason) {
                failedRebalanceMap[currencyId] = uint32(block.timestamp);
                emit RebalancingFailed(currencyId, reason);
            }
        }
    }

    function checkRebalance()
        public
        view
        returns (uint16[] memory currencyIdsToProcess)
    {
        uint16[] memory currencyIds = NOTIONAL.checkRebalance();

        // skip any currency that failed in previous rebalance that
        // happened after block.timestamp - DELAY_AFTER_FAILURE period
        uint16 numOfCurrencyIdsToProcess = 0;
        for (uint256 i = 0; i < currencyIds.length; i++) {
            if (
                failedRebalanceMap[currencyIds[i]] + DELAY_AFTER_FAILURE <
                block.timestamp
            ) {
                currencyIds[numOfCurrencyIdsToProcess++] = currencyIds[i];
            }
        }

        if (numOfCurrencyIdsToProcess > 0) {
            currencyIdsToProcess = new uint16[](
                numOfCurrencyIdsToProcess
            );
            for (uint256 i = 0; i < numOfCurrencyIdsToProcess; i++) {
                currencyIdsToProcess[i] = currencyIds[i];
            }
        }
    }
}
设置
{
  "compilationTarget": {
    "contracts/bots/RebalanceHelper.sol": "RebalanceHelper"
  },
  "evmVersion": "cancun",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": [
    ":@openzeppelin-4.6/=node_modules/@openzeppelin-4.6/",
    ":@openzeppelin/=node_modules/@openzeppelin/",
    ":ds-test/=lib/forge-std/lib/ds-test/src/",
    ":forge-std/=lib/forge-std/src/",
    ":hardhat/=node_modules/hardhat/",
    ":murky/=lib/murky/",
    ":openzeppelin-contracts/=lib/murky/lib/openzeppelin-contracts/"
  ]
}
ABI
[{"inputs":[{"internalType":"contract NotionalProxy","name":"notionalAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CurrencyIdsLengthCannotBeZero","type":"error"},{"inputs":[],"name":"CurrencyIdsNeedToBeSorted","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"currencyId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"reason","type":"bytes"}],"name":"RebalancingFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"currencyId","type":"uint16"}],"name":"RebalancingSucceeded","type":"event"},{"inputs":[],"name":"DELAY_AFTER_FAILURE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NOTIONAL","outputs":[{"internalType":"contract NotionalProxy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RELAYER_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkAndRebalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"checkRebalance","outputs":[{"internalType":"uint16[]","name":"currencyIdsToProcess","type":"uint16[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"currencyId","type":"uint16"}],"name":"failedRebalanceMap","outputs":[{"internalType":"uint32","name":"lastFailedRebalanceTimestamp","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16[]","name":"currencyIds","type":"uint16[]"}],"name":"rebalanceCurrencyIds","outputs":[],"stateMutability":"nonpayable","type":"function"}]