oDAO Membership Interest - peteris

Oracle DAO Proposal #13 - Atlas upgrade

The Oracle DAO proposal to upgrade the contracts for Atlas is now on-chain. It can be voted on by Oracle DAO members in 7 days (April 17, 2023) and if it passes it will be executed by the team on April 18, 2023 at 00:00 UTC.

Here is how this upgrade works:

  • An Oracle DAO member (this time it was rocketpool-2) submits a proposal to add a new contract
  • The upgrade contract address is encoded in the proposal payload
  • There is a 7 day delay before voting starts (April 17)
  • The team can configure the upgrade contract when it’s not locked
  • The team will lock the upgrade contract after the next rewards interval (April 13)
  • The team will verify the upgrade contract and the new versions of contracts on Etherscan
  • Oracle DAO members vote for the proposal
  • If 51% (10 out of 18) of Oracle DAO members vote for it by May 29 it will succeed
  • Succeeded proposal then needs to be executed
  • It will be executed by the team at the official Atlas launch time (April 18 or when the vote reaches the quorum)
  • When the upgrade contract is executed, it will replace the addresses of some Rocket Pool contracts with the new Atlas versions
  • It will also add new contracts, set new settings and also change existing settings

You can determine what exactly will be executed by decoding the payload, getting the upgrade contract address and verifying what the contract at this address does.

You can see the decoded payload of the proposal on Rocketscan:

Or you can verify it yourself:

  1. Grab the payload from the transaction on Etherscan (More details → Decode Input Data)
  2. Go to https://playground.ethers.org
  3. Paste this code and replace the placeholder with the payload
new ethers.utils.Interface(['function proposalUpgrade(string action, string contractName, string contractABI, address contractAddress)']).decodeFunctionData('proposalUpgrade', '0xdfc970ef...')

You should see:

  • Contract name: rocketUpgradeOneDotTwo
  • Contract ABI: eJzVms9P4zoQ...
  • Contract address: 0x9a0b5d3101d111EA0edD573d45ef2208CC97984a (etherscan, beaconcha.in)

The contract ABI is compressed with zlib and base64-encoded. Here is a script to decode the ABI. You can also run it in your browser on replit.

Script to decode the payload and contract ABI
const ethers = require('ethers') // npm install ethers@5
const pako = require('pako') // npm install pako@2

// proposal payload
// https://etherscan.io/tx/0x2495669bf2479617ff09f1399a632893f8c866b4701152c73de80457d0f644d8
const payload = '0xdfc970ef000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000009a0b5d3101d111ea0edd573d45ef2208cc97984a000000000000000000000000000000000000000000000000000000000000000b616464436f6e74726163740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016726f636b6574557067726164654f6e65446f7454776f000000000000000000000000000000000000000000000000000000000000000000000000000000000528654a7a566d733950347a6f51782f2b567035343532493664324e78596f5a583277443457396f59514774766a4b7149767152494846713334333539447934616d53524f67422b2b746a582f4e78312b5037526e35357663694c39614e7278656e4e2b31506a31554271353950613179634c6b785a2b41714d2f2b65714e50666f7233315a77524b2f745a5563474679634c417234723631345637327463475a74685855646976326d4839682b654c34395764516550463430486e532b797631544b43334b596731506f4666597451676a31373571544f6777664b7a7a5a51472b71666f6c7a796476724c2f395977332b517450347472657938563370764a4664557869666c305676575049727054796c5376434a5565334f7348745471737479316331624e2b7a4c392b483565636a786364432b6c366d417769394f773452673339364551694b4e564750324c7446664461743277487a3455326d50344c4449483451776b6a43617364366b37356e566850394d70454e6d76525939642b51766a5239674e634736312b6c727534484f54365a6236315759375747376a7163356b38355a5373633033357077544c64774d724645616a67305a44784f59567843464b46737a4e6f43487a644f63583732372f665334732b7171594e5058365033656247734c2f496958322b4d6a63684a4f426f6a32506a4f4e425071544f654875634b2b472b6f505957314c6a6b6f6c69644c634a47494f315756562b744b557131656b633179586465376a6b696b784172586c733962654346427345686c6e4954577a466c36664b4535586f744a4b6d736e304d305352695a525a4b31566952382b4551306a7462684758514a496d4b6a5877595a72497846466f4b414446615a7a4e426e415a6e6363775152786a633037556a6941324553786853544a4468456739584572674b614b5a62663835726e414a506a4c58646a6f784b5458767834684d446b303443734f6e4c79367648462b686a576166496c5044535a6571644e717665785352695a454949734b4a4957646a58454152677545714c6a45673553376c5972345957347249784241684e4257457a2f6677487730326b65315361494768634b4e706c5747477949524949474f57716d6b6876714e2f4c4b76374c374343776d4273795347466e4b526d2b747a755555516d426b2b4635697a4c356d4a387864694553494379314d34344b3934515243594356564961554e4f42337862687373716a3877644872414b4f6f366d34595962496845674a4f494675426b534935714c4d383344436b3478782b7836437945527745704a4d6a5364316478487931675464684e74666e49454641785769314d78396c43597963516a4c6e4e56322b6b7262346b52356e513358514b6370546b644962776769453045694956717a65534a6365376a6632426152434134596c5a6153397842454a6b4c6d4646504d546c396a722f41524b6c76486c7a3144744e7859314f386869457745514a59426c614f65554f314551312b676a75783053496c5447664a52436662746a3077416c566c4277593647515432417372425861427354323647676d5244385143703846434d794f5451466b69566964462b742f6f4b5156434549776b585070386557794d31745a39666439687675502f384a3151626553577a4d332b314335335766723233637a57474e7533662b7a7a396a454a4b4571434e5445385237727a72755076636f354f37417135434f39567333786c475a4863307770614d7837774e57396162647843735a4f6251754e7758487a5239795a376c745865763266314b425258593d000000000000000000000000000000000000000000000000'

// https://github.com/rocket-pool/rocketpool/blob/master/contracts/interface/dao/node/RocketDAONodeTrustedProposalsInterface.sol
const iface = new ethers.utils.Interface([
  'function proposalInvite(string id, string url, address nodeAddress)',
  'function proposalLeave(address nodeAddress)',
  'function proposalKick(address nodeAddress, uint256 rplFine)',
  'function proposalSettingUint(string settingContractName, string settingPath, uint256 value)',
  'function proposalSettingBool(string settingContractName, string settingPath, bool value)',
  'function proposalUpgrade(string type, string name, string contractABI, address contractAddress)'
])

const result = iface.decodeFunctionData(iface.getFunction(payload.substring(0, 10)), payload)

console.log(Object.fromEntries(Object.entries(result).filter(([key]) => isNaN(key)))) // filter out duplicate unnamed args

if (result.type == 'addContract' || result.type == 'upgradeContract') {
  const abi = JSON.parse(pako.inflate(Buffer.from(result.contractABI, 'base64'), { to: 'string' }))
  //console.log(abi) // json format
  console.log(Object.keys(new ethers.utils.Interface(abi).functions))
}

This is likely the source code of the upgrade contract: RocketUpgradeOneDotTwo.sol. I am waiting for the upgrade contract at 0x9a0b5d3101d111EA0edD573d45ef2208CC97984a to be verified on Etherscan before continuing my due dillegence.

2 Likes