Mento oracles migration

Context

Oracles are a critical component of Mento’s stability mechanism on Celo. These price feeds enable the protocol to facilitate exchanges between Mento collateral and stable assets at accurate market prices. Furthermore, price data is essential for Mento V2’s circuit breaker architecture, which safeguards the protocol against potential manipulation attacks and extreme market volatility, protecting the reserve collateral.

As many of you know, Mento Labs currently operates several Oracle clients that provide price data to SortedOracles. This arrangement was necessary at the protocol’s launch, as no external oracle providers were available when Celo mainnet went live. The operational complexity of maintaining these oracles has increased significantly with Mento V2’s expansion, which introduced more stable tokens and corresponding exchange pools.

Along the road, some initiatives were started to provide the opportunity for community members to operate oracle clients, reducing our operational burden and decreasing oracle operator centralization:

The Oracle landscape on Celo has improved significantly since then, and Chainlink and Redstone now provide high-quality feeds that all projects across the network can use.

Currently, Redstone delivers price data for seven feeds used by Mento V2:

  1. CELO/USD
  2. CELO/EUR
  3. CELO/BRL
  4. USDC/USD
  5. USDC/EUR
  6. USDC/BRL
  7. EUROC/EUR

While Chainlink delivers price data for the majority of Mento’s latest stable tokens launches:

  1. $PUSO
  2. $cCOP
  3. $cGHS
  4. $cGBP
  5. $cZAR
  6. $cCAD
  7. $cAUD
  8. $cCHF
  9. $cNGN
  10. $cJPY

Because of the above, we propose migrating Mento V2 rate feeds to be solely provided by Chainlink and Redstone.

This means concretely, removing all Mento-operated oracle addresses on-chain, leaving either Chainlink or Redstone as the sole price provider for each feed. We have conducted historical data comparisons between all Oracle providers across all pairs, confirming that the data provided by Chainlink and Redstone matches our expectations in terms of price quality as well as report frequency/uptime. For example, here are the plot comparison plots for CELO/USD and CELO/EUR across all three providers from early this year.

Since this proposal requires destroying and recreating some Mento Pools, we will also take this opportunity to review and optimize certain parameters, specifically spread and bucket sizes. A second forum post prior to submitting this proposal will provide more details on the concrete new values proposed.

Technical details

We propose the following split across providers:

  1. Redstone to remain as the single oracle provider on all the pools that it currently reports to:

    1. cUSD/CELO
    2. cEUR/CELO
    3. cREAL/CELO
    4. cUSD/USDC
    5. cEUR/USDC
    6. cREAL/USDC
    7. cUSD/axlUSDC
    8. cEUR/axlUSDC
    9. cREAL/axlUSDC
    10. cEUR/axlEUROC
  2. Chainlink to become the single oracle provider for the rest of the rate feeds that Mento Labs’ oracle clients currently provide:

    1. CELO/eXOF
    2. CELO/cKES
    3. EUROC/XOF
    4. EUR/XOF
    5. USDT/USD
    6. KES/USD

    In addition to remaining as the oracle providers for the pools which are already chainlink operated (e.g. cUSD/PUSO, cUSD/cCOP, cUSD/cJPY, etc).

The migration process for each rate feed will follow these steps:

  1. Remove all Mento Labs oracle addresses from sortedOracles (sortedOracles.removeOracle), except for Redstone
  2. Add new Chainlink relayer addresses to pools previously operated by Mento Labs
  3. Destroy the associated pool (BiPoolManager.destroyExchange)
  4. Recreate the pool with updated configuration:
    • Set minimumReports to 1
    • Update referenceRateResetFrequency to 6 minutes (aligning with recent token launch parameters)
    • Optionally implement new values for spread and stablePoolResetSize

What’s next

We are excited to complete this migration, as it will enhance Mento Protocol’s decentralization while freeing up significant engineering resources. The current operational complexity of maintaining multiple Oracle clients requires substantial infrastructure and development effort.

A detailed list of transactions included in the proposal, along with comprehensive verification steps for the community, will be provided in a separate forum post before the proposal submission.

Follow-up posts and status updates will be posted in this thread, so stay tuned!

5 Likes

In that case we will be removing the oracles commands from the celocli

4 Likes

Thanks @n-mlabs and team for the proposal, at my end this proposal is fulfilling all the requirements:

  • Post a proposal in the Celo Forum and leave it for discussion at least for seven (7) days.
  • Present Proposal in a Governance Call and address the feedback received: Proposal was presented during Celo Governance Call #68 | May 15th, 2025

With the above said, from my end the proposal is ready to move into the voting phase when proposer wants to move forward or consider is appropriate.


:bangbang: Remember Current Celo Governance Overview & Procedures

To proceed to the submission and voting phase at least two Celo Governance Guardians must post explicitly that the proposal fulfills the requirements to be able to move into the Voting Stage in the proposal thread on the Celo Forum.


Remember next steps

  • Submission of PR to Celo Governance Repository
    Proposers needs to fork the Celo Governance Repository and add a PR including the proposal .md file and json file.
  • Approval of PR by Celo governance Guardians and merge into main branch of Celo Governance Repository.
    Celo Guardians are responsible for conducting a comprehensive review of every Pull Request (PR) to ensure that there is complete alignment and consistency between the final proposal posted in the forum post and the specific files that are being requested to be merged.
    This review process is strictly technical in nature, focusing solely on verifying the authenticity and good faith of the proposers. It does not involve any personal opinions or biases regarding the merits or content of the proposal itself. To maintain the integrity of the Celo Governance repository, it is mandatory to obtain approval from a minimum of two Governance Guardians for each PR before it can be merged into the main branch.
  • OnChain Submission of Proposal
    After PR is merged into main Governance Repo the proposers needs to fork locally the Celo Governance Repository and submit the proposal onchain using the guidelines described in the Celo Docs.

CC: Governance Working Group (@annaalexa @Wade @0xGoldo)

4 Likes

Thanks @n-mlabs and team for the proposal. Confirming the proposal is ready to be moved to the next stage as outlined above

4 Likes

Hi folks! Due to technical constraints, we had to split the on-chain proposal into two parts since the full migration exceeded Celo’s block gas limit. Both proposals are now available:

CGP184: Mento Oracles Migration pt. 1
CGP186: Mento Oracles Migration pt. 2

This post guides you through verifying the transactions included in these proposals. You can follow along using the raw transactions found in the mainnet.json files (CGP184, CGP186) in the Celo governance repo.

We have prepared for this migration by:

  • Testing the proposal on Alfajores
  • Simulating the proposal on a fork of Celo Mainnet
  • Running comprehensive tests against the fork

While the proposals contain many transactions, they follow a straightforward structure. The first proposal (CGP184) focuses solely on removing old whitelisted oracle addresses, which comprises most of the migration transactions. The second proposal (CGP186) completes the migration by whitelisting the new Chainlink relayers, configuring report expiry times, and recreating the pools with updated parameters.

To follow along with each section and transaction, you’ll find these tools helpful:

For the tech-savvy, you can find all the details we’re describing here in our deployment tooling repository as code, in the file OracleRemoval.sol for CGP184 and OracleMigration.sol for CGP186. To verify the addresses included in the proposal, please refer to the Appendix below.

CGP184 - Mento Oracles Migration pt. 1

Remove Current Whitelisted Addresses (129 Transactions)

This proposal contains 129 transactions, all of the same type: calls to the the sortedOracles.removeOracle() function. It removes all current whitelisted addresses from each migrating feed, except for the Redstone adapter contract (0x6490a3FFAD86CA14FF84Be380D5639Fb8fBD311B).

Here’s a breakdown of the first transaction. These verification steps apply to all transactions:

TX#0 - Remove a whitelisted oracle from the CELO/USD feed

  • Verify the SortedOracles address
  • Verify the arguments:
    • token: The rate feed identifier (in this case, the cUSD token address)
      • 0x765DE816845861e75A25fCA122bb6898B8B1282a
    • oracle: The address of the whitelisted oracle to remove
      • 0xBBd6e54Af7A5722f42461C6313F37Bd50729F195

To view the list of whitelisted addresses for any rate feed identifier in the SortedOracles contract, use celocli:

celocli oracle:list <rateFeed> --node <https://forno.celo.org

or foundry

cast call 0xefb84935239dacdecf7c5ba76d8de40b077b7b33 "getOracles(address)(address[])" "<rateFeed>" --rpc-url <https://forno.celo.org

For a complete list of the identifiers used in this proposal, please refer to the appendix at the end of this post.

CGP186 - Mento Oracles Migration pt. 2

Whitelist New Relayers (9 txs)

The second proposal begins by whitelisting 9 new Chainlink relayer addresses for pools that Mento Labs previously operated. These relayers have been deployed and will be whitelisted in the following order:

  1. CELO/XOF - 0x242631D81A6eb2516a2A51C31240929d514Ea202
  2. EUROC/XOF - 0x9B5B7e9CE62b465C627EDd088E8907C1CBFCAa80
  3. EUR/XOF - 0x22e78caFCD7eaDD7907328Be22E0C6D66Ce363B3
  4. CELO/KES - 0x698Ac749cF4Eb5E9E8D903e2F222275E53416B54
  5. KES/USD - 0x4920101408D129a1A7B33fB0ECA4FB0233FD00D4
  6. USDT/USD - 0x564dD5fec58E7103C2A6041B7dD1BB3074a4616b
  7. EUR/USD - 0xC4918A76A7fdB113f2dFa9B162e875f271A2f7b8
  8. BRL/USD - 0x6322A90B468C14d1091CC91bC42FAd5584312220
  9. XOF/USD - 0xF2772e9EF0C1bc2794f7c21cf35843391bC32A5A

Note that the last three (EUR/USD, BRL/USD, and XOF/USD) are not currently in use, but we are whitelisting them now for an upcoming Mento Upgrade proposal.

Here’s a breakdown of the first two transactions in this section. These verification steps apply to all subsequent transactions:

TX#0 - Whitelist Chainlink relayer for eXOF/CELO

  • Verify the SortedOracles address
  • Verify the arguments:
    • token: The rate feed identifier (in this case, the eXOF token address)
      • 0x73F93dcc49cB8A239e2032663e9475dd5ef29A08
    • oracle: The address of the Chainlink relayer to add
      • 0x242631D81A6eb2516a2A51C31240929d514Ea202

TX#1 - Whitelist Chainlink relayer for EUROC/XOF

  • Verify the SortedOracles address
  • Verify the arguments:
    • token: The rate feed identifier
      • address(uint160(uint256(keccak256("EUROCXOF"))))
        • 0xeD35e46b095197dA30DdFFA5B91d386886d5ce0d
    • oracle: The address of the Chainlink relayer to add
      • 0x9B5B7e9CE62b465C627EDd088E8907C1CBFCAa80

Set Token Report Expiry (17 txs)

The next 17 transactions of the proposal set the tokenReportExpiry parameter on sortedOracles to 6 minutes for all rate feeds.

Here is a breakdown of the first two transactions in this section. The same verification steps apply to all transactions:

TX#9 - Set report expiry for CELO/USD

  • Verify the SortedOracles address
  • Verify the arguments:
    • token: The rate feed identifier (in this case, the cUSD token address)
      • 0x765DE816845861e75A25fCA122bb6898B8B1282a
    • reportExpirySeconds: The new report expiry time in seconds
      • 360 (6 minutes)

TX#10 - Set report expiry for CELO/EUR

  • Verify the SortedOracles address
  • Verify the arguments:
    • token: The rate feed identifier (in this case, the cEUR token address)
      • 0xD8763CBa276a3738E6DE85b4b3bF5FDed6D6cA73
    • reportExpirySeconds: The new report expiry time in seconds
      • 360 (6 minutes)

Note: The final transaction of this section, TX#25, sets the report expiry time for the PHP/USD rate feed. While this feed is already operated by Chainlink with a 5 minute report expiry time (set during CGP146/MU07), we are updating it to 6 minutes for consistency across all feeds.

Recreate Exchanges with New Config (30 txs)

The last 30 transactions of the proposal destroy and recreate the exchange pools with updated configuration parameters. The new configuration includes:

  • Setting minimumReports to 1
  • Setting referenceRateResetFrequency to 6 Minutes
  • Optionally, setting new parameters for spread and stablePoolResetSize

The following pools will have a new updated spread as part of this proposal:

Pool current spread (fee) proposed spread (fee)
cUSD/USDC 0% 0.05%
cUSD/axlUSDC 0% 0.25%
cEUR/axlUSDC 0.25% 0.5%
cREAL/axlUSDC 0.25% 0.5%
cEUR/axlEUROC 0.02% 0.5%
cUSD/USDT 0% 0.05%
eXOF/CELO 0.5% 2%
eXOF/axlEUROC 0.25% 2%

The following pools will have a new updated stablePoolResetSize as part of this proposal:

Pool current stablePoolResetSize proposed stablePoolResetSize
cUSD/CELO 7_200_000 3_000_000

Below is a breakdown of the first 4 transactions in this section. The same verification steps apply to all remaining transactions.

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.

TX#26 - Destroy the cUSD/PUSO exchange

  • Verify the BiPoolManager address
    • 0x22d9db95E6Ae61c104A7B6F6C78D7993B94ec901
  • Verify the arguments:
    • exchangeId: The deterministic id of the cUSD/PUSO exchange
      • 0x7952984d7278ca3417febf52815c321984ac3147ced2c02bb6a02b0bcab08413

TX#27 - Recreate cUSD/PUSO exchange with new config

  • Verify the BiPoolManager address
  • Verify the exchange configuration

TX#28 - Destroy the cUSD/USDT exchange

  • Verify the BiPoolManager address
    • 0x22d9db95E6Ae61c104A7B6F6C78D7993B94ec901
  • Verify the arguments:
    • exchangeId: The deterministic id of the cUSD/USDT exchange
      • 0x773bcec109cee923b5e04706044fd9d6a5121b1a6a4c059c36fdbe5b845d4e9b?

TX#29 - Recreate cUSD/USDT exchange with new config

  • Verify the BiPoolManager address
  • Verify the exchange configuration

Appendix: Verifying an address

Contracts

Please refer to this section of the Mento docs for a complete list of contract addresses for both Stable tokens (like cUSD, cEUR) and core Mento Protocol contracts (like BiPoolManager).

You’ll also find the following external addresses in the transactions that recreate the cUSD/CELO, cUSD/USDC, cUSD/USDT, cUSD/axlUSDC, and cEUR/axlEUROC exchanges:

Rate feed identifiers

The following rate feed identifiers were used in this proposal. Please refer to the mento docs for an additional explanation on rate feed identifiers:

Rate Feed Identifier Explanation
CELO/USD 0x765DE816845861e75A25fCA122bb6898B8B1282a The cUSD contract address
CELO/EUR 0xD8763CBa276a3738E6DE85b4b3bF5FDed6D6cA73 The cEUR contract address
CELO/BRL 0xe8537a3d056DA446677B9E9d6c5dB704EaAb4787 The cREAL contract address
CELO/XOF 0x73F93dcc49cB8A239e2032663e9475dd5ef29A08 The eXOF contract address
CELO/KES 0x456a3D042C0DbD3db53D5489e98dFb038553B0d0 The cKES contract address
USDC/USD 0xA1A8003936862E7a15092A91898D69fa8bCE290c address(uint160(uint256(keccak256("USDCUSD"))))
USDC/EUR 0x206B25Ea01E188Ee243131aFdE526bA6E131a016 address(uint160(uint256(keccak256("USDCEUR"))))
USDC/BRL 0x25F21A1f97607Edf6852339fad709728cffb9a9d address(uint160(uint256(keccak256("USDCBRL"))))
EUROC/EUR 0x26076B9702885d475ac8c3dB3Bd9F250Dc5A318B address(uint160(uint256(keccak256("EUROCEUR"))))
EUROC/XOF 0xed35e46b095197da30ddffa5b91d386886d5ce0d address(uint160(uint256(keccak256("EUROCXOF"))))
EUR/XOF 0x40dc8528167557353fdcd98548ab2139a670dd0b address(uint160(uint256(keccak256("EURXOF"))))
USDT/USD 0xE06C10C63377cD098b589c0b90314bFb55751558 address(uint160(uint256(keccak256("USDTUSD"))))
KES/USD 0xbAcEE37d31b9f022Ef5d232B9fD53F05a531c169 address(uint160(uint256(keccak256("KESUSD"))))
PHP/USD 0xab921d6ab1057601A9ae19879b111fC381a2a8E9 address(uint160(uint256(keccak256("relayed:PHPUSD"))))
EUR/USD 0xF4f9bBdA9CD6841fCB9b1510f9269E2dB42a6e3a address(uint160(uint256(keccak256("relayed:EURUSD"))))
BRL/USD 0x9dB83bE97C82912cB342407dd7b880983052B9c1 address(uint160(uint256(keccak256("relayed:BRLUSD"))))
XOF/USD 0x43620310c2FEADbFEcFd71b5A93E6e28946d64a5 address(uint160(uint256(keccak256("relayed:XOFUSD"))))

Exchange IDs

Please refer to this section of the Mento docs for an explanation on exchange identifiers as well as the complete list of identifiers per exchange.

1 Like

As TUM Blockchain Club, we would like to vote YES for this proposal because migrating to reliable external oracle providers like Chainlink and Redstone significantly enhances decentralization and security of Mento’s price feeds, reducing dependency on Mento Labs’ internal infrastructure and lowering the risk of manipulation or downtime—crucial for maintaining trust and stability in the protocol.

1 Like