Skip to content

Create automation pallet for EuroBrasil project #357

@ebma

Description

@ebma

Context

The context can be found in this Notion page.

Pallet configuration

Name

  • forex-automation

Config Items

  • PalletId - a PalletId used to derive the on-chain accounts for the automation and the buffer pool

Storage Items

  • NablaRouterAddress - the address of Nabla’s router smart contract
  • EurcErc20Address - the address of the ERC-20 wrapper contract for the EURC token
  • BrzErc20Address - the address of the ERC-20 wrapper contract for the BRZ token
  • OfframpAccount - the address of the designated off-ramping account. !TBD! This might not be required based on the EUR issuer
  • ReferenceToEurAmount - a map from Reference -> Balance which is used to store the desired target amount of EUR that were initially shown to the user upon creating a transfer request in PendulumPay. We store the amount and not an exchange rate because this way we don't have to incorporate any (on-ramp or XCM) fees that might have been deducted from the BRZ amount until it arrives on our parachain.
  • AuthorizedAccounts - a list of authorized accounts that are allowed to add entries to the ReferenceToEurAmount map

Extrinsics

  • setNablaRouterAddress(address) - sets the address of the router contract. Root extrinsic
  • setErc20Adresses(eurcAddress, brzAddress) - sets the addresses of the erc-20 contracts. Root extrinsic
  • setOfframpAccount(address) - sets the address of the offramping account. Root extrinsic
  • addEurAmountForReference(reference, amount) - adds an entry to the ReferenceToEurAmount. Only accounts registered in AuthorizedAccounts are allowed to call this extrinsic.
  • addAuthorizedAccount(account) - adds an authorized account to AuthorizedAccounts. Callable from Root and other authorized accounts
  • removeAuthorizedAccount(account) - removes an authorized account from AuthorizedAccounts. Callable from Root and other authorized accounts.
  • chargeBufferPoolAccount(currency) - transfers tokens to the pallet's buffer pool account. This is a mere helper function that makes it easy to charge the pool without having to know the address of the buffer pool. Callable from anyone. We don't need to limit the currencies that can be used with this function, but generally, it would only be used to charge the buffer pool with BRZ or EURC tokens.

Functions (not exposed as extrinsic but available to other pallets)

  • processEurcOfframp(amount, reference) - this function is called by the XCM config of our runtime. It handles the conversion from BRZ → EUR and transfers the tokens to the offramping account. amount is the amount of BRZ tokens that are to be offramped and reference is the reference that was encoded by the MultiLocation
  • getPalletAccount() - this function returns the account of this pallet, derived from the PalletId configuration parameter. This can be done with <T as Config>::PalletId::get().into_sub_account_truncating(0)
  • getBufferPoolAccount() - this function returns the account of the pool buffer, derived from the PalletId configuration parameter. This can be done with <T as Config>::PalletId::get().into_sub_account_truncating(1)

Events

  • TransferProcessed(reference, amount, currency) - emitted after sending the swapped tokens to the designated offramping account.
  • TransferPaused(reference, amount, currency) - emitted when the offramp cannot be executed with the targeted amount. This happens if the buffer pool does not have enough funds to cover the rest or if a Nabla swap is too expensive.

Coupling to other pallets

  • Contracts - needed to call the nabla contracts
  • Tokens - needed for the transfer
  • System - needed to set the remark

Processing the offramp

Prerequisites

Upon receiving an XCM transfer of BRZ from Moonbeam targeting our automation pallet, the XCM config deposits the respective amount of BRZ into this pallet’s on-chain account (returned by getPalletAccount()) and calls the processEurcOfframp() function, supplying the processed amount of BRZ and the reference number (which is encoded in the MultiLocation).

Implementation of the processEurcOfframp(amount, reference) function

The processEurcOfframp() function checks if there is an entry for the supplied reference parameter in the ReferenceToEurAmount map. If so, it uses the call() function of the Contracts pallet to call the swapExactTokensForTokens() function on Nabla’s router smart contract to swap the amount of BRZ tokens to EURC tokens. As a result, it will receive the corresponding amount of EURC on its on-chain account.
The swapExactTokensForTokens() function needs to be called using the addresses of the ERC-20 contracts. The signature of the function can be found here.
The amount of EURC tokens received as a result of calling the swapExactTokensForTokens() function is matched against the amount contained in the entry of the ReferenceToEurAmount map. If the resulting amount of the swap is higher than what was expected in the entry, the surplus of EURC tokens is sent to the buffer pool account.
If the resulting amount of the swap is less than what was expected in the entry, the pallet tries to transfer the missing amount of tokens from the buffer pool to the pallet account. If the buffer pool does not have enough tokens to cover all of the missing amount, the pallet does not continue processing this transfer but emits a TransferPaused event instead.

Next, the pallet calls the transfer() function of the Tokens pallet to transfer the available EURC on the pallet account to the offramping account and emits a TransferProcessed event. !TBD! this might have to change depending on the EUR issuer

Continuing from paused transfers

This is not part of this ticket but is covered in #378.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions