Skip to content

Instantly share code, notes, and snippets.

const sig = signature.value;
const r = '0x' + sig.substring(2).substring(0, 64);
const s = '0x' + sig.substring(2).substring(64, 128);
const v = '0x' + sig.substring(2).substring(128, 130);
@ajb413
ajb413 / net_apy.md
Last active November 28, 2023 06:11
How to calculate the Net APY that is displayed for users on https://app.compound.finance/

Net APY Calculation

  1. Convert all supplied and borrowed asset amounts to a single asset (like USD or ETH).
  2. Calculate the sum of (suppliedAmount * supplyApyAsDecimal - borrowedAmount * borrowApyAsDecimal) for all underlying assets.
  3. If the calculated sum from the previous step is >0 then Net APY = 100 * (sum / totalSuppliedValue). If the calculation from the previous step is <0 then Net APY = 100 * (sum / totalBorrowedValue). If the calculation from the previous step is 0 then Net APY = 0.

Example

Net APY:

  • -7.29%
@ajb413
ajb413 / getAllAssetInfos.js
Created October 20, 2023 16:46
Find out the price feed information for each asset supported by Compound Comet
const ethers = require('ethers'); // v5
const providerUrl = process.env.POLYGON_PROVIDER_URL;
(async () => {
const provider = new ethers.providers.JsonRpcProvider(providerUrl);
const cometAddress = '0xF25212E676D1F7F89Cd72fFEe66158f541246445';
const cometAbi = [
'function getAssetInfo(uint8 i) public view returns (uint8 offset, address asset, address priceFeed, uint64 scale, uint64 borrowCollateralFactor, uint64 liquidateCollateralFactor, uint64 liquidationFactor, uint128 supplyCap)',
'function baseToken() public view returns (address)',
'function baseTokenPriceFeed() public view returns (address)',
@ajb413
ajb413 / EIP712.js
Last active September 3, 2023 15:01
Module for creating EIP-712 signatures with Ethers.js as the only dependency. Works in the browser and Node.js (Ethers.js Web3 Provider / JSON RPC Provider).
// Based on https://github.com/ethereum/EIPs/blob/master/assets/eip-712/Example.js
const ethers = require('ethers');
function abiRawEncode(encTypes, encValues) {
const hexStr = ethers.utils.defaultAbiCoder.encode(encTypes, encValues);
return Buffer.from(hexStr.slice(2, hexStr.length), 'hex');
}
function keccak256(arg) {
@ajb413
ajb413 / Get_COMP_APY.md
Last active August 8, 2023 11:03
Finding the COMP APY

From Blockchain With JSON RPC and JavaScript

const Compound = require('@compound-finance/compound-js');

const provider = 'https://mainnet.infura.io/v3/' + process.env.infuraApiKey;

const cTokenToGetCompApy = Compound.cUSDC; // Pick an asset

const underlying = cTokenToGetCompApy.slice(1, 10);
const underlyingDecimals = Compound.decimals[underlying];
@ajb413
ajb413 / comp_earned.md
Last active July 27, 2023 15:19
How do I retrieve the "COMP earned" value from the Compound protocol? Get the amount of accrued COMP token for an address using the Ethereum blockchain.

How do I retrieve the "COMP earned" value?

With a Smart Contract or JSON RPC

Get the value of COMP earned for an address that uses the Compound protocol. This can be done using the Lens contract with JSON RPC or another Smart Contract. If you do an eth_call with JSON RPC, it is free (no gas costs).

  1. Use the getCompBalanceMetadataExt method in the Lens contract https://etherscan.io/address/0xdCbDb7306c6Ff46f77B349188dC18cEd9DF30299#code
  2. Lens address is posted here https://github.com/compound-finance/compound-protocol/blob/master/networks/mainnet.json#L31
  3. Here is the definition https://github.com/compound-finance/compound-protocol/blob/master/contracts/Lens/CompoundLens.sol#L453
@ajb413
ajb413 / comet-abi-98f438b.json
Last active May 31, 2023 21:45
Compound III Comet Main Interface at compound/finance/comet repository commit 98f438b.
[{"inputs":[],"name":"Absurd","type":"error"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"BadAmount","type":"error"},{"inputs":[],"name":"BadAsset","type":"error"},{"inputs":[],"name":"BadDecimals","type":"error"},{"inputs":[],"name":"BadDiscount","type":"error"},{"inputs":[],"name":"BadMinimum","type":"error"},{"inputs":[],"name":"BadNonce","type":"error"},{"inputs":[],"name":"BadPrice","type":"error"},{"inputs":[],"name":"BadSignatory","type":"error"},{"inputs":[],"name":"BorrowCFTooLarge","type":"error"},{"inputs":[],"name":"BorrowTooSmall","type":"error"},{"inputs":[],"name":"InsufficientReserves","type":"error"},{"inputs":[],"name":"InvalidInt104","type":"error"},{"inputs":[],"name":"InvalidInt256","type":"error"},{"inputs":[],"name":"InvalidUInt104","type":"error"},{"inputs":[],"name":"InvalidUInt128","type":"error"},{"inputs":[],"name":"InvalidUInt64","type":"error"},{"inputs":[],"name":"InvalidValueS","type":"error"},{"inputs":[],"name":"InvalidValueV","type":"error"}
@ajb413
ajb413 / deploy.js
Last active August 24, 2022 03:15
A Node.js script for deploying a smart contract to the locally hosted Ethereum instance.
const fs = require('fs');
const Web3 = require('web3');
const web3 = new Web3('http://localhost:8545');
const bytecode = fs.readFileSync('./build/FirstContract.bin');
const abi = JSON.parse(fs.readFileSync('./build/FirstContract.abi'));
(async function () {
const ganacheAccounts = await web3.eth.getAccounts();
const myWalletAddress = ganacheAccounts[0];
@ajb413
ajb413 / minte-usdc.js
Created October 21, 2020 00:04
Local host fork of mainnet, "steal" some test USDC from a whale (cUSDC contract).
// First run Ganache locally with `cUsdc` address unlocked
const Web3 = require('web3');
const web3 = new Web3('http://127.0.0.1:8545');
const usdcAbi = [{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorizer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"AuthorizationCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorizer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"AuthorizationUsed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_account","type":"address"}],"name":"Blacklist
@ajb413
ajb413 / compound-liquidation-example.md
Created March 16, 2022 19:45
A Compound v2 Liquidation Example

A borrower account has Dai collateral and an open WBTC borrow. It has become under-collateralized. I can seize their cDai by liquidating their WBTC borrow. I have a balance of WBTC. I call approve on cWBTC and pass the amount of WBTC that I want to repay (or greater). I then call liquidateBorrow on cWBTC and pass the borrower address, amount of WBTC to liquidate, and the cDai address. If the liquidation is successful, my WBTC balance goes down and my cDai balance goes up. If I redeem that cDai immediately, the underlying Dai is worth the same amount as the amount of WBTC I gave up plus 8%.