Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions docs/MIP-R38.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# MIP-R38: Moonriver Complete Deprecation

### **Summary**
This proposal recommends reducing collateral factors on Moonriver markets from 7.5% to 0% as part of the ongoing wind-down of Moonriver lending activity. This will affect xcKSM, MOVR, and FRAX markets respectively.

Chainlink has announced plans to deprecate oracle feeds on Moonriver, materially increasing oracle risk for remaining positions. In advance of this deadline, Anthias Labs has recommended continuing to lower collateral factors toward zero to reduce protocol exposure and encourage orderly position closure.

This proposal represents the next step in that process.

### **Background**
Over a month ago, the Moonwell community received knowledge that Chainlink is deprecating its price feeds across the Moonriver network. Out of concern for Moonwell's users, we believe the best course of actions is to slowly deprecate the respective markets affected on Moonwell's Moonriver implementation: xcKSM, FRAX, and MOVR.

### **Proposal**

If this proposal is successful, the following markets will have their current collateral factors changed to the proposed collateral factors:

| Market | Current Collateral Factor | Proposed Collateral Factor |
|--------|---------------------------|----------------------------|
| xcKSM | 7.5% | 0% |
| MOVR | 7.5% | 0% |
| FRAX | 7.5% | 0% |

These recommendations were provided by Anthias Labs in their forum post: [Anthias Recommendations](https://forum.moonwell.fi/t/anthias-labs-risk-parameter-recommendations/1759/9)

### **Rationale**

Lowering the collateral factors on Moonriver assets is a necessary and responsible step to ensure a safe wind-down of the affected markets ahead of Chainlink price feed deprecation. Once these feeds go offline, Moonwell would no longer be able to reliably determine asset values on Moonriver. This completes the slow wind down of the Moonriver markets.

### **Voting Options**

- **For:** Approve collateral factor changes to the Moonriver markets.
- **Against:** Do not make collateral factor changes to the Moonriver markets.
- **Abstain:** No preference.
47 changes: 47 additions & 0 deletions test/apollo/mip-r38/generateProposalData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import {ethers} from "ethers";
import {BigNumber as EthersBigNumber} from "@ethersproject/bignumber/lib/bignumber";
import {addProposalToPropData, ProposalData} from "../../../src";
import {ContractBundle} from "@moonwell-fi/moonwell.js";
import {COLLATERAL_FACTOR_CHANGES} from "./vars";
import BigNumber from "bignumber.js";

function cfPercentToMantissa(newCFPercent: number){
return EthersBigNumber.from(
new BigNumber(newCFPercent)
.div(100)
.times(new BigNumber('1e18'))
.toFixed(0)
)
}

export async function generateProposalData(contracts: ContractBundle, provider: ethers.providers.JsonRpcProvider){
const comptroller = contracts.COMPTROLLER.contract.connect(provider)

const proposalData: ProposalData = {
targets: [],
values: [],
signatures: [],
callDatas: [],
}

// Add collateral factor changes for each market
const cfOrder = ['xcKSM', 'MOVR', 'FRAX'] // Fixed order
for (const marketTicker of cfOrder) {
const newCF = COLLATERAL_FACTOR_CHANGES[marketTicker]
if (newCF !== undefined) {
const market = contracts.MARKETS[marketTicker]
if (market) {
console.log(` Adding CF change for ${marketTicker}: ${newCF}% (mToken: ${market.mTokenAddress})`)
await addProposalToPropData(comptroller, '_setCollateralFactor',
[
market.mTokenAddress,
cfPercentToMantissa(newCF)
],
proposalData
)
}
}
}

return proposalData
}
78 changes: 78 additions & 0 deletions test/apollo/mip-r38/getCalldata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import {ethers} from 'ethers'
import {Contracts} from '@moonwell-fi/moonwell.js'
import {generateProposalData} from "./generateProposalData"
import {RPC_URL, STARTING_COLLATERAL_FACTORS, COLLATERAL_FACTOR_CHANGES} from "./vars"
import * as fs from 'fs'
import * as path from 'path'

async function main() {
const contracts = Contracts.moonriver
const provider = new ethers.providers.JsonRpcProvider(RPC_URL)

console.log('\n===========================================')
console.log('MIP-R38: Moonriver Complete Deprecation')
console.log('===========================================\n')

console.log('Governor Address:', contracts.GOVERNOR.address)
console.log('Expected:', '0x2BE2e230e89c59c8E20E633C524AD2De246e7370')
console.log('Match:', contracts.GOVERNOR.address === '0x2BE2e230e89c59c8E20E633C524AD2De246e7370' ? '✅' : '❌')
console.log()

console.log('Generating proposal data...\n')
const proposalData = await generateProposalData(contracts, provider)

// Read the full proposal description from the markdown file
const markdownPath = path.join(__dirname, '../../../docs/MIP-R38.md')
const description = fs.readFileSync(markdownPath, 'utf-8')

console.log('✅ Loaded full markdown proposal from docs/MIP-R38.md')
console.log(`Description length: ${description.length} characters\n`)

console.log('=== PROPOSAL DESCRIPTION ===\n')
console.log(description)
console.log('\n=== END DESCRIPTION ===\n')

console.log('=== PROPOSAL DATA ===\n')
console.log(JSON.stringify(proposalData, null, 2))
console.log('\n=== SUMMARY ===')
console.log(`Total actions: ${proposalData.targets.length}`)
console.log(`Target (Comptroller): ${proposalData.targets[0]}`)
console.log('\nActions:')
const cfMarkets = ['xcKSM', 'MOVR', 'FRAX']
proposalData.signatures.forEach((sig, i) => {
console.log(` ${i + 1}. ${sig} - ${cfMarkets[i]} CF`)
})
console.log('\nCollateral Factor Changes:')
for (const market of cfMarkets) {
const oldCF = STARTING_COLLATERAL_FACTORS[market]
const newCF = COLLATERAL_FACTOR_CHANGES[market]
console.log(` - ${market}: ${oldCF}% → ${newCF}%`)
}

// Encode the propose function call
console.log('\n===========================================')
console.log('ENCODED PROPOSE CALLDATA')
console.log('===========================================\n')

const governor = contracts.GOVERNOR.contract.connect(provider)
const proposeCalldata = await governor.populateTransaction.propose(
proposalData.targets,
proposalData.values,
proposalData.signatures,
proposalData.callDatas,
description
)

console.log('To:', contracts.GOVERNOR.address)
console.log('Data:', proposeCalldata.data)
console.log('\nCalldata Length:', proposeCalldata.data!.length, 'characters')
console.log('\nYou can submit this transaction to the Governor contract at:')
console.log('https://moonriver.moonscan.io/address/' + contracts.GOVERNOR.address + '#writeContract')
}

main()
.then(() => process.exit(0))
.catch(error => {
console.error(error)
process.exit(1)
})
24 changes: 24 additions & 0 deletions test/apollo/mip-r38/vars.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export * from '../base-vars'

// Fork block - using a recent Moonriver block
export const FORK_BLOCK = 3_900_000

// RPC URL - use environment variable or fallback to public RPC
export const RPC_URL = process.env.MOONRIVER_RPC_URL || 'https://rpc.api.moonriver.moonbeam.network'

// Markets to update collateral factors
export const MARKETS_TO_UPDATE = ['xcKSM', 'MOVR', 'FRAX']

// Starting collateral factors (current values)
export const STARTING_COLLATERAL_FACTORS: { [key: string]: number } = {
'xcKSM': 7.5,
'MOVR': 7.5,
'FRAX': 7.5
}

// New collateral factors
export const COLLATERAL_FACTOR_CHANGES: { [key: string]: number } = {
'xcKSM': 0,
'MOVR': 0,
'FRAX': 0
}
Loading