-
Notifications
You must be signed in to change notification settings - Fork 14
Description
Context
The context can be found in this Notion page.
Pallet configuration
Name
forex-automation
Config Items
PalletId- aPalletIdused to derive the on-chain accounts for the automation and the buffer pool
Storage Items
NablaRouterAddress- the address of Nabla’sroutersmart contractEurcErc20Address- the address of the ERC-20 wrapper contract for the EURC tokenBrzErc20Address- the address of the ERC-20 wrapper contract for the BRZ tokenOfframpAccount- the address of the designated off-ramping account. !TBD! This might not be required based on the EUR issuerReferenceToEurAmount- a map fromReference -> Balancewhich 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 theReferenceToEurAmountmap
Extrinsics
setNablaRouterAddress(address)- sets the address of theroutercontract. Root extrinsicsetErc20Adresses(eurcAddress, brzAddress)- sets the addresses of the erc-20 contracts. Root extrinsicsetOfframpAccount(address)- sets the address of the offramping account. Root extrinsicaddEurAmountForReference(reference, amount)- adds an entry to theReferenceToEurAmount. Only accounts registered inAuthorizedAccountsare allowed to call this extrinsic.addAuthorizedAccount(account)- adds an authorized account toAuthorizedAccounts. Callable from Root and other authorized accountsremoveAuthorizedAccount(account)- removes an authorized account fromAuthorizedAccounts. 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.amountis the amount of BRZ tokens that are to be offramped andreferenceis the reference that was encoded by theMultiLocationgetPalletAccount()- this function returns the account of this pallet, derived from thePalletIdconfiguration 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 thePalletIdconfiguration 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.