> For the complete documentation index, see [llms.txt](https://docs.mayaprotocol.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.mayaprotocol.com/mayachain-dev-docs/aggregators/evm-implementation.md).

# EVM Implementation

MAYAChain Aggregator Example

{% embed url="<https://gitlab.com/mayachain/ethereum/eth-router/-/blob/master/contracts/MAYAChain_Aggregator.sol?ref_type=heads>" %}

Tokens must be on the ETH Whitelist (LINK). The destination address should be a user control address, not a contract address.

### SwapIn

The aggregator contract needs a **swapIn** function similar to the one below. First, swap the token via an on-chain AMM, then call into MAYAChain and pass the correct memo to execute the next swap.

```go
 function swapIn(
        address tcVault,
        address tcRouter,
        string calldata tcMemo,
        address token,
        uint amount,
        uint amountOutMin,
        uint256 deadline
        ) public nonReentrant {
        uint256 _safeAmount = safeTransferFrom(token, amount); // Transfer asset
        safeApprove(token, address(swapRouter), amount);
        address[] memory path = new address[](2);
        path[0] = token; path[1] = WETH;
        swapRouter.swapExactTokensForETH(_safeAmount, amountOutMin, path, address(this), deadline);
        _safeAmount = address(this).balance;
        iROUTER(tcRouter).depositWithExpiry{value:_safeAmount}(payable(tcVault), ETH, _safeAmount, tcMemo, deadline);
    }
```

Transaction Example (LINK). Note the destination address is not a contract address.

### SwapOut

The MAYAChain router uses `transferOutAndCall()` to call the aggregator with a max GasLimit of 400k units.

It is a particular function that also handles a swap fail by sending the user the base asset directly (ie, breached AmountOutMin, or could not find the finaltoken). The user will need to do the swap manually.

The parameters for this function are passed to MAYAChain by the user's original memo.

```go
function transferOutAndCall(address payable target, address finalToken, address to, uint256 amountOutMin, string memory memo) public payable nonReentrant {
        uint256 _safeAmount = msg.value;
        (bool erc20Success, ) = target.call{value:_safeAmount}(abi.encodeWithSignature("swapOut(address,address,uint256)", finalToken, to, amountOutMin));
        if (!erc20Success) {
            bool ethSuccess = payable(to).send(_safeAmount); // If can't swap, just send the recipient the ETH
            if (!ethSuccess) {
                payable(address(msg.sender)).transfer(_safeAmount); // For failure, bounce back to Yggdrasil & continue.
            }
        }
        emit TransferOutAndCall(msg.sender, target, _safeAmount, finalToken, to, amountOutMin, memo);
    }
```

The **swapOut** function will only be passed three parameters from the MAYAChain Router and it must comply with the function signature (name, parameters). It can then call an on-chain AMM to execute the swap. It will only ever be given the base asset (eg ETH).

Here is an example to call UniV2 router:

```go
function swapOut(address token, address to, uint256 amountOutMin) public payable nonReentrant {
        address[] memory path = nelw address[](2);
        path[0] = WETH; path[1] = token;
        swapRouter.swapExactETHForTokens{value: msg.value}(amountOutMin, path, to, type(uint).max);
    }
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.mayaprotocol.com/mayachain-dev-docs/aggregators/evm-implementation.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
