Monerium Swapper Helper

High-Level Overview

The SwapperHelper contract is a helper utility that performs 1:1 swaps between a collateral token and a stablecoin on behalf of a user. It coordinates a three-way token movement where:

  • The caller supplies stablecoin (EUR0) and receives collateral (EURe).

  • The recipient supplies collateral (EURe) and receives stablecoin (EUR0).

The contract supports both standard ERC20 approvals and ERC20 Permit-based approvals (EIP-2612) for the collateral token, enabling gasless approval flows for EOAs. An optional operator role can be configured to restrict who is allowed to initiate swaps.

Contract Summary

SwapperHelper sits between a collateral token (EURe) and a stablecoin (EUR0) and enforces a 1:1 exchange rate between them, assuming they share the same number of decimals. The contract.

Key Features

1:1 Swap Mechanism

  • Swaps collateral and stablecoin at a 1:1 rate, enforced by equal decimals on both tokens.

  • The caller ends up with collateral; the recipient ends up with stablecoin.

Permit-Based Approval Flow

  • swapOnBehalfWithPermit uses IERC20Permit to approve collateral spending via signature.

  • Allows recipients to authorize swaps without an on-chain approval transaction (EOA only).

Functions Description

Public / External Functions

  • swapOnBehalfWithPermit(address recipient, uint256 maxAmount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) Performs a 1:1 swap using an ERC20 Permit signature for collateral.

    • Parameters:

      • recipient: Address providing collateral and receiving stablecoin.

      • maxAmount: Maximum collateral amount to swap (and stablecoin to transfer).

      • deadline: Permit deadline; reverts if block.timestamp > deadline.

      • v, r, s: ECDSA signature components for the permit.

    • Requirements:

      • COLLATERAL_TOKEN supports permit.

      • Signature must authorize recipientthis for maxAmount until deadline.

      • Caller must have approved sufficient stablecoin allowance to this.

      • deadline must not be expired; otherwise reverts with DeadlineExpired().

      • Operator check must pass (see _swapOnBehalf).

  • swapOnBehalf(address recipient, uint256 maxAmount) Performs a 1:1 swap based on pre-existing ERC20 approvals (no permit).

    • Parameters:

      • recipient: Address providing collateral and receiving stablecoin.

      • maxAmount: Maximum collateral amount to swap (and stablecoin to transfer).

    • Requirements:

      • recipient must have approved this contract to spend collateral.

      • Caller must have approved this contract to spend stablecoin.

      • Operator check must pass.

  • changeOperator(address newOperator) Updates the operator address.

    • Parameters:

      • newOperator: New operator address (can be zero to make swaps permissionless).

State Variables

  • COLLATERAL_TOKEN Collateral token is EURe and used in swaps (must implement permit for swapOnBehalfWithPermit).

  • STABLECOIN Stablecoin token is EUR0 and used in swaps.

  • operator Optional operator address restricting who can initiate swaps. address(0) means permissionless.

Error Handling

  • NullAddress(): Thrown when a required address parameter is zero.

  • DeadlineExpired(): Thrown when a provided permit deadline has already passed.

  • ZeroAmount(): Thrown when a swap or recovery amount resolves to zero.

  • NotAuthorized(): Thrown when a non-operator initiates a swap while an operator is configured.

  • InsufficientBalance(): Thrown if stablecoin balance check after transfer fails, indicating an unexpected token behavior.

  • InvalidDecimals(): Thrown in the constructor when collateral and stablecoin decimals differ.

  • NotAllowed(): Thrown when attempting to renounce ownership.

  • SameValue(): Thrown when collateral and stablecoin addresses are the same.

Security Considerations

Immutable Token References

  • COLLATERAL_TOKEN and STABLECOIN are immutable and set once in the constructor.

  • Prevents arbitrary token reconfiguration.

Decimal Consistency

  • Validates equal decimals for collateral and stablecoin at deployment.

  • Ensures 1:1 swaps are value-consistent in token units.

Operator Access Control

  • Optional operator limit reduces who can execute swaps in controlled environments.

  • Owner can update the operator or set it to zero for permissionless use.

Balance Verification

  • After transferring stablecoin from caller to contract, the contract checks that its balance increased as expected.

  • Protects against non-standard ERC20 implementations that do not behave as expected.

Reentrancy and Token Safety

  • Uses SafeERC20 for all token transfers.

  • The stablecoin and collateral transfers are ordered to minimize risk; the final transfer (safeTransferFrom of collateral) is from the recipient to the caller.

  • Comments acknowledge arbitrary ERC20 sends, justified because the recipient is the intended beneficiary of stablecoin.

Ownership Retention

  • Ownership cannot be renounced, ensuring a responsible address for operator and recovery actions.

Token Recovery

  • Owner-only recoverERC20 prevents tokens from being permanently stuck in the contract.

Integration Notes

  • Token Requirements

    • COLLATERAL_TOKEN:

      • Must be ERC20-compliant.

      • Must implement IERC20Permit for the permit-based swap function.

    • STABLECOIN:

      • Standard ERC20.

    • Both tokens must:

      • Have identical decimals().

      • Be distinct addresses.

  • Using swapOnBehalfWithPermit

    1. Recipient signs an ERC20 Permit approving this contract to spend up to maxAmount collateral.

    2. Caller provides the signature parameters and maxAmount.

    3. Contract attempts the permit (non-fatal if it fails) and then swaps up to the minimum of:

      • Recipient’s collateral allowance to the contract.

      • Recipient’s collateral balance.

      • Provided maxAmount.

  • Using swapOnBehalf

    1. Recipient approves this contract to spend collateral.

    2. Caller approves this contract to spend stablecoin.

    3. Caller calls swapOnBehalf(recipient, maxAmount).

    4. Swap executes for the capped amount as above.

  • Operator Configuration

    • For open, permissionless swaps, deploy with _operator = address(0) or later call changeOperator(address(0)).

    • For controlled environments (e.g., only a specific router or backend), set _operator to that address.

  • Event Usage

    • Listen to SwapOnBehalf(caller, recipient, amount) (defined in ISwapperHelper) to index executed swaps.

    • Listen to OperatorChanged(newOperator) to track operator role changes.

Last updated

Was this helpful?