# 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 `recipient` → `this` 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://tech.usual.money/smart-contracts/utility-contracts/eur0/monerium-swapper-helper.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
