/** * InsuranceFundClient — AereInsuranceFund helpers. * Permissionless donate; Foundation-only coverBadDebt. * * Contract: aerenew/contracts/contracts/lending/AereInsuranceFund.sol */ export interface RpcProvider { request(args: { method: string; params: unknown[] }): Promise; } const pad32 = (h: string) => h.toLowerCase().replace(/^0x/, '').padStart(64, '0'); const encUint = (n: bigint) => pad32(n.toString(16)); const encAddr = (a: string) => pad32(a.replace(/^0x/, '')); async function ethCall(p: RpcProvider, to: string, data: string): Promise { return await p.request({ method: 'eth_call', params: [{ to, data }, 'latest'] }) as string; } async function ethSend(p: RpcProvider, from: string, to: string, data: string): Promise { return await p.request({ method: 'eth_sendTransaction', params: [{ from, to, data, value: '0x0' }] }) as string; } const SEL = { FOUNDATION: '0x4d09f93e', // FOUNDATION() COOLDOWN_SECONDS: '0xb47d5cf5', // COOLDOWN_SECONDS() markets: '0x2c43cab8', // markets(address) balances: '0x27e235e3', // balances(address) coverageRemaining: '0x1d29df0e', // coverageRemaining(address) cooldownReady: '0x3a09a73e', // cooldownReady(address) registerMarket: '0xc6da18d4', // registerMarket(address,uint256) donate: '0xf14fcbc8', // donate(address,uint256) coverBadDebt: '0xa90c1e1c', // coverBadDebt(address,address,uint256) } as const; export class AereInsuranceFundClient { constructor(public readonly provider: RpcProvider, public readonly address: string) {} async getFoundation(): Promise { return '0x' + (await ethCall(this.provider, this.address, SEL.FOUNDATION)).slice(-40); } async getCooldownSeconds(): Promise { return BigInt(await ethCall(this.provider, this.address, SEL.COOLDOWN_SECONDS)); } async balanceOf(token: string): Promise { return BigInt(await ethCall(this.provider, this.address, SEL.balances + encAddr(token))); } async coverageRemaining(market: string): Promise { return BigInt(await ethCall(this.provider, this.address, SEL.coverageRemaining + encAddr(market))); } async cooldownReady(market: string): Promise { const r = await ethCall(this.provider, this.address, SEL.cooldownReady + encAddr(market)); return BigInt(r) === 1n; } /** * Permissionless donate. Caller must approve `token` for `amount` on the fund first. */ async donate(from: string, token: string, amount: bigint): Promise { return ethSend(this.provider, from, this.address, SEL.donate + encAddr(token) + encUint(amount)); } /** Foundation-only: register a market with a lifetime coverage cap. */ async registerMarket(from: string, market: string, lifetimeCap: bigint): Promise { return ethSend(this.provider, from, this.address, SEL.registerMarket + encAddr(market) + encUint(lifetimeCap)); } /** Foundation-only: pay down `amount` of `borrower`'s debt on `market`. */ async coverBadDebt(from: string, market: string, borrower: string, amount: bigint): Promise { return ethSend(this.provider, from, this.address, SEL.coverBadDebt + encAddr(market) + encAddr(borrower) + encUint(amount)); } }