ZapperARM

Description:

Multi-signature wallet contract requiring multiple confirmations for transaction execution.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "src/contracts/ZapperARM.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.23;

// Contracts
import {Ownable} from "./Ownable.sol";

// Interfaces
import {IWETH} from "./Interfaces.sol";
import {IERC20} from "./Interfaces.sol";
import {ILiquidityProviderARM} from "./Interfaces.sol";

/**
 * @title Zapper contract for Automated Redemption Managers (ARMs)
 * Converts native currency to wrapped currency, deposits it to an ARM and receives ARM LP shares.
 * @author Origin Protocol Inc
 */
contract ZapperARM is Ownable {
    /// @notice The address of the wrapped token. eg WETH or wS
    IWETH public immutable wrappedCurrency;

    event Zap(address indexed arm, address indexed sender, uint256 assets, uint256 shares);

    constructor(address _wrappedCurrency) {
        wrappedCurrency = IWETH(_wrappedCurrency);
    }

    /// @notice Convert native currency to wrapped currency, deposit it to an ARM and receive ARM shares
    /// @param arm The address of the ARM contract to deposit to
    /// @return shares The amount of ARM LP shares sent to the depositor
    function deposit(address arm) public payable returns (uint256 shares) {
        // Wrap all native currency sent
        uint256 balance = address(this).balance;
        wrappedCurrency.deposit{value: balance}();

        // Deposit all wrapped currency to the ARM
        wrappedCurrency.approve(arm, balance);
        shares = ILiquidityProviderARM(arm).deposit(balance, msg.sender);

        // Emit event
        emit Zap(arm, msg.sender, balance, shares);
    }

    /// @notice Rescue ERC20 tokens
    /// @param token The address of the ERC20 token
    /// @param amount The amount of tokens to rescue
    function rescueERC20(address token, uint256 amount) external onlyOwner {
        IERC20(token).transfer(msg.sender, amount);
    }
}
"
    },
    "src/contracts/Ownable.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

/**
 * @title Base contract that provides ownership control
 * @author Origin Protocol Inc
 */
contract Ownable {
    /// @notice The slot used to store the owner of the contract.
    /// This is also used as the proxy admin.
    /// keccak256(“eip1967.proxy.admin”) - 1 per EIP 1967
    bytes32 internal constant OWNER_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;

    event AdminChanged(address previousAdmin, address newAdmin);

    constructor() {
        assert(OWNER_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1));
        _setOwner(msg.sender);
    }

    /// @notice The contract owner and proxy admin.
    function owner() public view returns (address) {
        return _owner();
    }

    /// @notice Set the owner and proxy admin of the contract.
    /// @param newOwner The address of the new owner.
    function setOwner(address newOwner) external onlyOwner {
        _setOwner(newOwner);
    }

    function _owner() internal view returns (address ownerOut) {
        bytes32 position = OWNER_SLOT;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            ownerOut := sload(position)
        }
    }

    function _setOwner(address newOwner) internal {
        emit AdminChanged(_owner(), newOwner);
        bytes32 position = OWNER_SLOT;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            sstore(position, newOwner)
        }
    }

    function _onlyOwner() internal view {
        require(msg.sender == _owner(), "ARM: Only owner can call this function.");
    }

    modifier onlyOwner() {
        _onlyOwner();
        _;
    }
}
"
    },
    "src/contracts/Interfaces.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

interface IERC20 {
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address to, uint256 value) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 value) external returns (bool);
    function transferFrom(address from, address to, uint256 value) external returns (bool);
    function decimals() external view returns (uint8);

    event Transfer(address indexed from, address indexed to, uint256 value);
}

interface IOethARM {
    function token0() external returns (address);
    function token1() external returns (address);
    function owner() external returns (address);

    /**
     * @notice Swaps an exact amount of input tokens for as many output tokens as possible.
     * msg.sender should have already given the ARM contract an allowance of
     * at least amountIn on the input token.
     *
     * @param inToken Input token.
     * @param outToken Output token.
     * @param amountIn The amount of input tokens to send.
     * @param amountOutMin The minimum amount of output tokens that must be received for the transaction not to revert.
     * @param to Recipient of the output tokens.
     */
    function swapExactTokensForTokens(
        IERC20 inToken,
        IERC20 outToken,
        uint256 amountIn,
        uint256 amountOutMin,
        address to
    ) external;

    /**
     * @notice Uniswap V2 Router compatible interface. Swaps an exact amount of
     * input tokens for as many output tokens as possible.
     * msg.sender should have already given the ARM contract an allowance of
     * at least amountIn on the input token.
     *
     * @param amountIn The amount of input tokens to send.
     * @param amountOutMin The minimum amount of output tokens that must be received for the transaction not to revert.
     * @param path The input and output token addresses.
     * @param to Recipient of the output tokens.
     * @param deadline Unix timestamp after which the transaction will revert.
     * @return amounts The input and output token amounts.
     */
    function swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    /**
     * @notice Receive an exact amount of output tokens for as few input tokens as possible.
     * msg.sender should have already given the router an allowance of
     * at least amountInMax on the input token.
     *
     * @param inToken Input token.
     * @param outToken Output token.
     * @param amountOut The amount of output tokens to receive.
     * @param amountInMax The maximum amount of input tokens that can be required before the transaction reverts.
     * @param to Recipient of the output tokens.
     */
    function swapTokensForExactTokens(
        IERC20 inToken,
        IERC20 outToken,
        uint256 amountOut,
        uint256 amountInMax,
        address to
    ) external;

    /**
     * @notice Uniswap V2 Router compatible interface. Receive an exact amount of
     * output tokens for as few input tokens as possible.
     * msg.sender should have already given the router an allowance of
     * at least amountInMax on the input token.
     *
     * @param amountOut The amount of output tokens to receive.
     * @param amountInMax The maximum amount of input tokens that can be required before the transaction reverts.
     * @param path The input and output token addresses.
     * @param to Recipient of the output tokens.
     * @param deadline Unix timestamp after which the transaction will revert.
     * @return amounts The input and output token amounts.
     */
    function swapTokensForExactTokens(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function setOwner(address newOwner) external;
    function transferToken(address token, address to, uint256 amount) external;

    // From OethLiquidityManager
    function requestWithdrawal(uint256 amount) external returns (uint256 requestId, uint256 queued);
    function claimWithdrawal(uint256 requestId) external;
    function claimWithdrawals(uint256[] calldata requestIds) external;
}

interface ILiquidityProviderARM is IERC20 {
    function previewDeposit(uint256 assets) external returns (uint256 shares);
    function deposit(uint256 assets) external returns (uint256 shares);
    function deposit(uint256 assets, address liquidityProvider) external returns (uint256 shares);

    function previewRedeem(uint256 shares) external returns (uint256 assets);
    function requestRedeem(uint256 shares) external returns (uint256 requestId, uint256 assets);
    function claimRedeem(uint256 requestId) external returns (uint256 assets);

    function totalAssets() external returns (uint256 assets);
    function convertToShares(uint256 assets) external returns (uint256 shares);
    function convertToAssets(uint256 shares) external returns (uint256 assets);
    function lastTotalAssets() external returns (uint256 assets);
}

interface ICapManager {
    function postDepositHook(address liquidityProvider, uint256 assets) external;
}

interface LegacyAMM {
    function transferToken(address tokenOut, address to, uint256 amount) external;
}

interface IOriginVault {
    function mint(address _asset, uint256 _amount, uint256 _minimumOusdAmount) external;

    function redeem(uint256 _amount, uint256 _minimumUnitAmount) external;

    function requestWithdrawal(uint256 amount) external returns (uint256 requestId, uint256 queued);

    function claimWithdrawal(uint256 requestId) external returns (uint256 amount);

    function claimWithdrawals(uint256[] memory requestIds)
        external
        returns (uint256[] memory amounts, uint256 totalAmount);

    function addWithdrawalQueueLiquidity() external;

    function setMaxSupplyDiff(uint256 _maxSupplyDiff) external;

    function governor() external view returns (address);

    function dripper() external view returns (address);

    function withdrawalQueueMetadata()
        external
        view
        returns (uint128 queued, uint128 claimable, uint128 claimed, uint128 nextWithdrawalIndex);

    function withdrawalRequests(uint256 requestId)
        external
        view
        returns (address withdrawer, bool claimed, uint40 timestamp, uint128 amount, uint128 queued);

    function withdrawalClaimDelay() external view returns (uint256);
}

interface IGovernance {
    enum ProposalState {
        Pending,
        Active,
        Canceled,
        Defeated,
        Succeeded,
        Queued,
        Expired,
        Executed
    }

    function state(uint256 proposalId) external view returns (ProposalState);

    function proposalSnapshot(uint256 proposalId) external view returns (uint256);

    function proposalDeadline(uint256 proposalId) external view returns (uint256);

    function proposalEta(uint256 proposalId) external view returns (uint256);

    function votingDelay() external view returns (uint256);

    function castVote(uint256 proposalId, uint8 support) external returns (uint256 balance);

    function queue(uint256 proposalId) external;

    function execute(uint256 proposalId) external;
}

interface IWETH is IERC20 {
    event Deposit(address indexed dst, uint256 wad);
    event Withdrawal(address indexed src, uint256 wad);

    function deposit() external payable;
    function withdraw(uint256 wad) external;
}

interface ISTETH is IERC20 {
    event Submitted(address indexed sender, uint256 amount, address referral);

    // function() external payable;
    function submit(address _referral) external payable returns (uint256);
}

interface IStETHWithdrawal {
    event WithdrawalRequested(
        uint256 indexed requestId,
        address indexed requestor,
        address indexed owner,
        uint256 amountOfStETH,
        uint256 amountOfShares
    );
    event WithdrawalsFinalized(
        uint256 indexed from, uint256 indexed to, uint256 amountOfETHLocked, uint256 sharesToBurn, uint256 timestamp
    );
    event WithdrawalClaimed(
        uint256 indexed requestId, address indexed owner, address indexed receiver, uint256 amountOfETH
    );

    struct WithdrawalRequestStatus {
        /// @notice stETH token amount that was locked on withdrawal queue for this request
        uint256 amountOfStETH;
        /// @notice amount of stETH shares locked on withdrawal queue for this request
        uint256 amountOfShares;
        /// @notice address that can claim or transfer this request
        address owner;
        /// @notice timestamp of when the request was created, in seconds
        uint256 timestamp;
        /// @notice true, if request is finalized
        bool isFinalized;
        /// @notice true, if request is claimed. Request is claimable if (isFinalized && !isClaimed)
        bool isClaimed;
    }

    function transferFrom(address _from, address _to, uint256 _requestId) external;
    function ownerOf(uint256 _requestId) external returns (address);
    function requestWithdrawals(uint256[] calldata _amounts, address _owner)
        external
        returns (uint256[] memory requestIds);
    function getLastCheckpointIndex() external view returns (uint256);
    function findCheckpointHints(uint256[] calldata _requestIds, uint256 _firstIndex, uint256 _lastIndex)
        external
        view
        returns (uint256[] memory hintIds);
    function claimWithdrawals(uint256[] calldata _requestIds, uint256[] calldata _hints) external;
    function getWithdrawalStatus(uint256[] calldata _requestIds)
        external
        view
        returns (WithdrawalRequestStatus[] memory statuses);
    function getWithdrawalRequests(address _owner) external view returns (uint256[] memory requestsIds);
    function getLastRequestId() external view returns (uint256);
}

interface IOracle {
    function price(address asset) external view returns (uint256 price);
}

interface IHarvestable {
    function collectRewards() external returns (address[] memory tokens, uint256[] memory rewards);
}

interface IMagpieRouter {
    function swapWithMagpieSignature(bytes calldata) external payable returns (uint256 amountOut);
}

library DistributionTypes {
    struct IncentivesProgramCreationInput {
        string name;
        address rewardToken;
        uint104 emissionPerSecond;
        uint40 distributionEnd;
    }
}

library IDistributionManager {
    struct AccruedRewards {
        uint256 amount;
        bytes32 programId;
        address rewardToken;
    }
}

interface SiloIncentivesControllerGaugeLike {
    function claimRewards(address _to) external returns (IDistributionManager.AccruedRewards[] memory accruedRewards);
    function createIncentivesProgram(DistributionTypes.IncentivesProgramCreationInput memory _incentivesProgramInput)
        external;
    function getAllProgramsNames() external view returns (string[] memory programsNames);
    function getRewardsBalance(address _user, string memory _programName)
        external
        view
        returns (uint256 unclaimedRewards);
    function incentivesPrograms(bytes32)
        external
        view
        returns (
            uint256 index,
            address rewardToken,
            uint104 emissionPerSecond,
            uint40 lastUpdateTimestamp,
            uint40 distributionEnd
        );
    function owner() external view returns (address);
}

interface IEETHWithdrawal {
    function requestWithdraw(address receipient, uint256 amount) external returns (uint256 requestId);
}

interface IEETHWithdrawalNFT {
    function finalizeRequests(uint256 requestId) external;
    function claimWithdraw(uint256 requestId) external;
    function batchClaimWithdraw(uint256[] calldata requestIds) external;
}

interface IEETHRedemptionManager {
    function redeemWeEth(uint256 amount, address receiver) external;
    function canRedeem(uint256 amount) external view returns (bool);
}

interface IDistributor {
    function claim(
        address[] calldata users,
        address[] calldata tokens,
        uint256[] calldata amounts,
        bytes32[][] calldata proofs
    ) external;
}
"
    }
  },
  "settings": {
    "remappings": [
      "dependencies/@pendle-sy-1.0.0-1.0.0/:@openzeppelin/contracts/=dependencies/@openzeppelin-contracts-4.9.3-4.9.3/contracts/",
      "contracts/=src/contracts/",
      "script/=script/",
      "test/=test/",
      "utils/=src/contracts/utils/",
      "@solmate/=dependencies/solmate-6.7.0/src/",
      "forge-std/=dependencies/forge-std-1.9.7/src/",
      "@pendle-sy/=dependencies/@pendle-sy-1.0.0-1.0.0/contracts/",
      "@openzeppelin/contracts/=dependencies/@openzeppelin-contracts-5.0.2-5.0.2/contracts/",
      "@openzeppelin/contracts-upgradeable/=dependencies/@openzeppelin-contracts-upgradeable-5.0.2-5.0.2/contracts/"
    ],
    "optimizer": {
      "enabled": true,
      "runs": 200
    },
    "metadata": {
      "useLiteralContent": false,
      "bytecodeHash": "ipfs",
      "appendCBOR": true
    },
    "outputSelection": {
      "*": {
        "*": [
          "evm.bytecode",
          "evm.deployedBytecode",
          "devdoc",
          "userdoc",
          "metadata",
          "abi"
        ]
      }
    },
    "evmVersion": "shanghai",
    "viaIR": false
  }
}}

Tags:
ERC20, Multisig, Mintable, Swap, Liquidity, Upgradeable, Multi-Signature, Factory|addr:0xe11edbd5ae4fa434af7f8d7f03da1742996e7ab2|verified:true|block:23689029|tx:0xaa37438b17f442d6bd2a3865f1698186b58b7b127b7c8a7b4481ee592590b446|first_check:1761829634

Submitted on: 2025-10-30 14:07:17

Comments

Log in to comment.

No comments yet.