[Proposal] Mento Upgrade MU06: Native USDT Integration

Overview

The team at Mento Labs is proposing the creation of a new trading pair on Mento: cUSD/USDT. This initiative aims to support our partners at Opera Mini Pay in their mission to offer accessible financial solutions to millions of users in Africa, powered by Mento. In addition to the new pair, we also propose reducing the spread of existing USDC/cUSD pools (nativeUSDC/cUSD and axlUSDC/cUSD) to 0, to facilitate easy on-and-off ramping from other stables to cUSD.

This post outlines the proposed transactions to activate the cUSD/USDT trading pair, enabling seamless and efficient exchanges between these two assets via the Mento protocol, as well as the transactions required to deploy new USDC pools with 0 spread. As with previous proposals, the Celo community will have the opportunity to review and verify these transactions.

To ensure a smooth launch, we have taken the following preparatory steps:

  • Simulated the CGP on testnets and executed post-execution checks to verify the parameters
  • Executed test swaps on testnets and on a fork of mainnet to confirm the new pairs were created and configured correctly

The prerequisite work for the creation of this pair was completed in a recent proposal:

  • Addition of USDTUSD oracles (CGP 135)

The transactions that will be in the upcoming CGP will be broken down into the following sections, noted here with the transaction indices in brackets:

  1. Add USDT as a reserve collateral asset (0-1)
  2. Remove existing exchanges that will be redeployed(2-3)
  3. Configure the new exchanges (4-6)
  4. Configure trading limits (7)
  5. Configure BreakerBox (8-9)
  6. Configure the ValueDeltaBreaker (10-12)

Before we dive into each section and transaction, we recommend you have celocli set up to follow along. For the tech-savvy, you can find everything we are describing here in our deployment tooling repository as code. To verify that the addresses included in the proposal are correct, please refer to the Appendix at the bottom for some tips.

1. Add USDT as a reserve collateral asset

TX#0 adds USDT as a collateral asset to the Reserve

  • Verify the ReserveProxy address
  • Verify the USDT address

TX#1 sets the daily spending ratio for USDT to 100%. The value is represented as a fixed point number with 24 decimals, i.e. 1 is written as 1e24 or 1000000000000000000000000

  • Verify the ReserveProxy address
  • Verify the USDT address
  • Verify the ratio: 1e24 = 100%

2. Remove existing exchanges that will be redeployed

After experimenting with constant sum pools and trading limits, we’ve decided to deploy the USDT/cUSD with a 0% spread to facilitate easy on-and-off ramping from centralized stables to cUSD, while feeling confident that the security that comes from our circuit breaker and trading limits provide enough security.

With that in mind, we’ll also set the spread to 0% on the cUSD/axlUSDC and cUSD/nativeUSDC pairs, so we must destroy them first and recreate them in the next step.

TX#2 destroys the existing cUSD/nativeUSDC exchange

  • Verify the BiPoolManagerProxy address
  • Verify the cUSD/nativeUSDC exchangeID
  • Verify the exchange index

TX#3 destroys the existing cUSD/axlUSDC exchange

  • Verify the BiPoolManagerProxy address
  • Verify the cUSD/axlUSDC exchangeID
  • Verify the exchange index

2. Configure the new exchange

:warning:Verification tip: As in previous proposals, we recommend ignoring the args field from celocli and focusing on params, as well as ignoring the numbered fields and instead focusing only on the named fields. This is due to how nested structs are serialized by celocli, which might make the payload look confusing.

The pool configuration structures are documented here: https://docs.mento.org/mento/developers/smart-contracts/bipoolmanager 3

TX#4 - recreate the cUSD/nativeUSDC exchange

  • Verify the BiPoolManagerProxy address
  • Verify the exchange configuration

TX#5 - recreate the cUSD/axlUSDC exchange

  • Verify the BiPoolManagerProxy address
  • Verify the exchange configuration

TX#6 - create the cUSD/nativeUSDT exchange

  • Verify the BiPoolManagerProxy address
  • Verify the exchange configuration

3. Configure trading limits

Similar to the previous section, the output of celocli is too verbose when dealing with arguments and structs, so it’s recommended to ignore args and numbered fields and to focus instead on params and named fields.

The TradingLimit.Config structure is documented here: TradingLimits | Mento Protocol 2

TX#7- configure trading limits on cUSD for the cUSD/USDT exchange

  • Verify BrokerProxy address
  • Verify the arguments:
    • exchangeId: the deterministic id of the cUSD/USDT exchange
    • token: which asset in the pair to target, in this case, the cUSD token address
    • config: the trading limit configuration

4. Configure the BreakerBox

Here we configure the BreakerBox to ensure it monitors changes to the new USDT/USD rate.

TX#8 - adding rate feeds to the BreakerBox:

  • Verify the BreakerBox address
  • Verify the arguments:
    • newRateFeedIDs an array of oracle feed ids. In this case, the array only contains the id of USDT/USD
      • USDT/USD - address(uint160(uint256(keccak256("USDTUSD"))))

TX#9 - enable the ValueDeltaBreaker on the USDT/USD rate feed

  • Verify the BreakerBox address
  • Verify the arguments:
    • breakerAddress should be the ValueDeltaBreaker
    • rateFeedID should be the identifier for the USDT/USD rate, i.e. address(uint160(uint256(keccak256("USDTUSD"))))
    • enable true

5. Configure the ValueDeltaBreaker

The ValueDeltaBreaker verifies that a new median is within a percentage threshold of a configurable reference value. These transactions configure the breaker with the necessary values to determine when the breaker should trip for the USDT/USD rate feed and how much time should pass before the breakers can be reset.

TX#10 Set the USDT/USD reference value for the ValueDeltaBreaker

  • Verify the ValueDeltaBreaker address
  • Verify the parameters:
    • rateFeedIDs: the array of rate feeds to configure, should contain the rate feed identifiers for:
      • USDT/USD: address(uint160(keccak256(“USDTUSD”)))
    • _referenceValues: the array of reference values to set, indices will match the rateFeedIDs array. The values are fixed point numbers – a number with 24 decimals, i.e. 1 is written as 1e24.
      • USDT/USD: 1e24

TX#11 Set the USDT/USD cooldown time for the ValueDeltaBreaker

  • Verify the ValueDeltaBreaker address
  • Verify the parameters:
    • rateFeedIDs: the array of rate feeds to configure, should contain the rate feed identifiers for:
      • USDT/USD: address(uint160(keccak256(“USDTUSD”)))
    • cooldownTimes: the array of cooldown times to be configured, the indices will match with the rateFeedIDs array. The values are seconds.
      • USDT/USD: 1

TX#12 Set the USDT/USD rate change percentage threshold for the ValueDeltaBreaker

  • Verify the ValueDeltaBreaker address
  • Verify the parameters:
    • rateFeedIDs: the array of rate feeds to configure, should contain the rate feed identifiers for:
      • USDT/USD: address(uint160(keccak256(“USDTUSD”)))
    • rateChangeThresholds: the array of rate change thresholds to be configured, the indices will match with the rateFeedIDs array. The values are fixed point numbers – a number with 24 decimals, i.e. 1 is written as 1e24.
      • USDT/USD: 5e21 = 0.005%

Appendix A: Verifying an address

Verifying that an address in the CGP is correct requires a few different strategies depending on what that address is. Here are common situations:

8 Likes