diff --git a/packages/contracts/src/strategies/ApeLendingStrategy.sol b/packages/contracts/src/strategies/ApeLendingStrategy.sol index 97ddf687..92d7c559 100644 --- a/packages/contracts/src/strategies/ApeLendingStrategy.sol +++ b/packages/contracts/src/strategies/ApeLendingStrategy.sol @@ -45,7 +45,7 @@ contract ApeLendingStrategy is SafeUUPSUpgradeable, CTokenBaseStrategy { /// @inheritdoc IVersionable function version() external pure override returns (string memory) { - return "0.3.1"; + return "0.3.2"; } // ------------------------------------------ Constructors ------------------------------------------ diff --git a/packages/contracts/src/strategies/CTokenBaseStrategy.sol b/packages/contracts/src/strategies/CTokenBaseStrategy.sol index ac33601c..8a1e838e 100644 --- a/packages/contracts/src/strategies/CTokenBaseStrategy.sol +++ b/packages/contracts/src/strategies/CTokenBaseStrategy.sol @@ -106,7 +106,7 @@ abstract contract CTokenBaseStrategy is ICInterestRate, BaseStrategy { } // in this case "PerBlock" actually means "PerSecond" - return cToken.borrowRatePerBlock() / secondPerBlock; + return cToken.borrowRatePerBlock() * secondPerBlock; } /// @inheritdoc ICInterestRate @@ -116,7 +116,7 @@ abstract contract CTokenBaseStrategy is ICInterestRate, BaseStrategy { } // in this case "PerBlock" actually means "PerSecond" - return cToken.supplyRatePerBlock() / secondPerBlock; + return cToken.supplyRatePerBlock() * secondPerBlock; } /// @inheritdoc ICInterestRate diff --git a/packages/contracts/test/unit/CTokenBaseStrategy.t.sol b/packages/contracts/test/unit/CTokenBaseStrategy.t.sol index 018334e2..80d07405 100644 --- a/packages/contracts/test/unit/CTokenBaseStrategy.t.sol +++ b/packages/contracts/test/unit/CTokenBaseStrategy.t.sol @@ -207,45 +207,48 @@ contract CTokenBaseStrategyTest is TestWithERC1820Registry { // test interestRatePerBlock function testShouldReturnCorrectInterestRatePerBlock( bool _blocksBased, - uint256 interestRatePerBlock + uint128 _interestRatePerBlock ) public { + uint256 interestRatePerBlock = _interestRatePerBlock; cToken.setBlocksBased(_blocksBased); cToken.setSupplyRatePerBlock(interestRatePerBlock); if (_blocksBased) { assertEq(strategy.interestRatePerBlock(), interestRatePerBlock); } else { - assertEq(strategy.interestRatePerBlock(), interestRatePerBlock / strategy.secondPerBlock()); + assertEq(strategy.interestRatePerBlock(), interestRatePerBlock * strategy.secondPerBlock()); } } // test borrowRatePerBlock function testShouldReturnCorrectBorrowRatePerBlock( bool _blocksBased, - uint256 borrowRatePerBlock + uint128 _borrowRatePerBlock ) public { + uint256 borrowRatePerBlock = _borrowRatePerBlock; cToken.setBlocksBased(_blocksBased); cToken.setBorrowRatePerBlock(borrowRatePerBlock); if (_blocksBased) { assertEq(strategy.borrowRatePerBlock(), borrowRatePerBlock); } else { - assertEq(strategy.borrowRatePerBlock(), borrowRatePerBlock / strategy.secondPerBlock()); + assertEq(strategy.borrowRatePerBlock(), borrowRatePerBlock * strategy.secondPerBlock()); } } // test supplyRatePerBlock function testShouldReturnCorrectSupplyRatePerBlock( bool _blocksBased, - uint256 supplyRatePerBlock + uint128 _supplyRatePerBlock ) public { + uint256 supplyRatePerBlock = _supplyRatePerBlock; cToken.setBlocksBased(_blocksBased); cToken.setSupplyRatePerBlock(supplyRatePerBlock); if (_blocksBased) { assertEq(strategy.supplyRatePerBlock(), supplyRatePerBlock); } else { - assertEq(strategy.supplyRatePerBlock(), supplyRatePerBlock / strategy.secondPerBlock()); + assertEq(strategy.supplyRatePerBlock(), supplyRatePerBlock * strategy.secondPerBlock()); } } diff --git a/packages/subgraph/generated/schema.ts b/packages/subgraph/generated/schema.ts index 9a74a675..fccd5efe 100644 --- a/packages/subgraph/generated/schema.ts +++ b/packages/subgraph/generated/schema.ts @@ -498,8 +498,8 @@ export class RewardAPY extends Entity { this.set("decimals", Value.fromI32(value)); } - get dayly(): BigInt { - let value = this.get("dayly"); + get daily(): BigInt { + let value = this.get("daily"); if (!value || value.kind == ValueKind.NULL) { throw new Error("Cannot return null for a required field."); } else { @@ -507,8 +507,8 @@ export class RewardAPY extends Entity { } } - set dayly(value: BigInt) { - this.set("dayly", Value.fromBigInt(value)); + set daily(value: BigInt) { + this.set("daily", Value.fromBigInt(value)); } get weekly(): BigInt { diff --git a/packages/subgraph/nodemon.json b/packages/subgraph/nodemon.json index 6729ab6c..a5685c15 100644 --- a/packages/subgraph/nodemon.json +++ b/packages/subgraph/nodemon.json @@ -1,6 +1,6 @@ { "watch": ["src", "tests"], "ext": "ts", - "exec": "yarn test" + "exec": "yarn test:local" } \ No newline at end of file diff --git a/packages/subgraph/package.json b/packages/subgraph/package.json index d8b29f35..2fe43b25 100644 --- a/packages/subgraph/package.json +++ b/packages/subgraph/package.json @@ -1,6 +1,6 @@ { "name": "@eonian/subgraph", - "version": "0.9.4", + "version": "0.9.5", "scripts": { "gen:code": "graph codegen ./deploy/environments/eonian-sepolia-testnet.yaml", "dev": "graph codegen ./deploy/environments/eonian-sepolia-testnet.yaml --watch", @@ -14,6 +14,7 @@ "deploy:local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 eonian-sepolia-testnet", "copy:local-schema": "cp ./deploy/environments/local.yaml ./subgraph.yaml", "test": "graph test", + "test:local": "yarn copy:local-schema && yarn test", "test:docker": "graph test -d", "test:watch": "nodemon", "gen:configs": "node bin/generate-yaml-configs.js ./deploy ./deploy/environments" diff --git a/packages/subgraph/schema.graphql b/packages/subgraph/schema.graphql index 23e13dd0..b11652ac 100644 --- a/packages/subgraph/schema.graphql +++ b/packages/subgraph/schema.graphql @@ -170,7 +170,7 @@ type RewardAPY @entity(immutable: false) @regularPolling { decimals: Int! " Dayly interest rate, represented as percentage scaled by 10^decimals " - dayly: BigInt! + daily: BigInt! " Weekly interest rate, represented as percentage scaled by 10^decimals " weekly: BigInt! diff --git a/packages/subgraph/src/apy/apy-calculations.ts b/packages/subgraph/src/apy/apy-calculations.ts index 71e29a4a..c283480f 100644 --- a/packages/subgraph/src/apy/apy-calculations.ts +++ b/packages/subgraph/src/apy/apy-calculations.ts @@ -1,6 +1,7 @@ import { Address, Bytes, ethereum, BigInt } from "@graphprotocol/graph-ts"; -export const MAX_BPS = 10_000; +export const MAX_BPS = 4; +export const INTEREST_RATE_DECIMALS = 18; export const PERCENTS_SCALE = BigInt.fromI64(100); // TODO: add values per chain @@ -10,9 +11,9 @@ export const BLOCK_TIME = 3.01; // In seconds, https://ycharts.com/indicators/bi export const SECONDS_PER_DAY: f64 = 60 * 60 * 24; -export const BLOCKS_PER_WEEK = BigInt.fromI64(Math.round((7 as f64) * SECONDS_PER_DAY * BLOCK_TIME) as i64); -export const BLOCKS_PER_MONTH = BigInt.fromI64(Math.round((30 as f64) * SECONDS_PER_DAY * BLOCK_TIME) as i64); -export const BLOCKS_PER_YEAR = BigInt.fromI64(Math.round((365 as f64) * SECONDS_PER_DAY * BLOCK_TIME) as i64); +export const BLOCKS_PER_WEEK = BigInt.fromI64(Math.round((7 as f64) * SECONDS_PER_DAY / BLOCK_TIME) as i64); +export const BLOCKS_PER_MONTH = BigInt.fromI64(Math.round((30 as f64) * SECONDS_PER_DAY / BLOCK_TIME) as i64); +export const BLOCKS_PER_YEAR = BigInt.fromI64(Math.round((365 as f64) * SECONDS_PER_DAY / BLOCK_TIME) as i64); /** * Returns APY in percents scaled by 10 ^ 18 diff --git a/packages/subgraph/src/apy/reward-apy-service.ts b/packages/subgraph/src/apy/reward-apy-service.ts index ea397ac6..456029f4 100644 --- a/packages/subgraph/src/apy/reward-apy-service.ts +++ b/packages/subgraph/src/apy/reward-apy-service.ts @@ -1,7 +1,7 @@ import { Bytes, BigInt } from "@graphprotocol/graph-ts"; import { RewardAPY } from "../../generated/schema" import {WithLogger} from '../logger' -import { MAX_BPS, BLOCKS_PER_DAY, BLOCKS_PER_WEEK, BLOCKS_PER_MONTH, BLOCKS_PER_YEAR, toApy } from "./apy-calculations"; +import { INTEREST_RATE_DECIMALS, BLOCKS_PER_DAY, BLOCKS_PER_WEEK, BLOCKS_PER_MONTH, BLOCKS_PER_YEAR, toApy } from "./apy-calculations"; export interface IRewardApyService { createOrUpdate(id: Bytes, interestRatePerBlock: BigInt): RewardAPY; @@ -18,11 +18,11 @@ export class RewardApyService extends WithLogger implements IRewardApyService { if(!entity) { this.logger.info("Creating new APY entity for {}", [id.toString()]) entity = new RewardAPY(id); - entity.decimals = MAX_BPS; + entity.decimals = INTEREST_RATE_DECIMALS; } this.logger.info("Filling APY entity for {}", [id.toString()]) - entity.dayly = toApy(interestRatePerBlock, BLOCKS_PER_DAY); + entity.daily = toApy(interestRatePerBlock, BLOCKS_PER_DAY); entity.weekly = toApy(interestRatePerBlock, BLOCKS_PER_WEEK); entity.monthly = toApy(interestRatePerBlock, BLOCKS_PER_MONTH); entity.yearly = toApy(interestRatePerBlock, BLOCKS_PER_YEAR); diff --git a/packages/subgraph/tests/.latest.json b/packages/subgraph/tests/.latest.json index a90abb27..59b768c4 100644 --- a/packages/subgraph/tests/.latest.json +++ b/packages/subgraph/tests/.latest.json @@ -1,4 +1,4 @@ { "version": "0.5.4", - "timestamp": 1688083670264 + "timestamp": 1688229780947 } \ No newline at end of file diff --git a/packages/subgraph/tests/reward-apy-service.test.ts b/packages/subgraph/tests/reward-apy-service.test.ts index 2709bd8f..33cb059b 100644 --- a/packages/subgraph/tests/reward-apy-service.test.ts +++ b/packages/subgraph/tests/reward-apy-service.test.ts @@ -13,7 +13,7 @@ import { MockLogger, mockViewFunction } from "./mocking" import { createUpgradedEvent } from "./vault-utils"; import { Context } from "../src/Context"; import { RewardApyService } from "../src/apy/reward-apy-service"; -import { MAX_BPS } from "../src/apy/apy-calculations"; +import { INTEREST_RATE_DECIMALS } from "../src/apy/apy-calculations"; const tokenAddress = Address.fromString("0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); const tokenAddressStr = tokenAddress.toHexString() @@ -52,12 +52,11 @@ describe("RewardApyService", () => { assert.entityCount("RewardAPY", 1) - assert.fieldEquals("RewardAPY", idStr, "decimals", MAX_BPS.toString()) - assert.fieldEquals("RewardAPY", idStr, "dayly", "353403600") - assert.fieldEquals("RewardAPY", idStr, "weekly", "22391510400") - assert.fieldEquals("RewardAPY", idStr, "monthly", "95963616000") - assert.fieldEquals("RewardAPY", idStr, "yearly", "1167557328000") - + assert.fieldEquals("RewardAPY", idStr, "decimals", INTEREST_RATE_DECIMALS.toString()) + assert.fieldEquals("RewardAPY", idStr, "daily", "353403600") + assert.fieldEquals("RewardAPY", idStr, "weekly", "2471439000") + assert.fieldEquals("RewardAPY", idStr, "monthly", "10591899000") + assert.fieldEquals("RewardAPY", idStr, "yearly", "128868034800") }) test("should update APY entity", () => { @@ -70,11 +69,11 @@ describe("RewardApyService", () => { assert.entityCount("RewardAPY", 1) - assert.fieldEquals("RewardAPY", idStr, "decimals", MAX_BPS.toString()) - assert.fieldEquals("RewardAPY", idStr, "dayly", "706807200") - assert.fieldEquals("RewardAPY", idStr, "weekly", "44783020800") - assert.fieldEquals("RewardAPY", idStr, "monthly", "191927232000") - assert.fieldEquals("RewardAPY", idStr, "yearly", "2335114656000") + assert.fieldEquals("RewardAPY", idStr, "decimals", INTEREST_RATE_DECIMALS.toString()) + assert.fieldEquals("RewardAPY", idStr, "daily", "706807200") + assert.fieldEquals("RewardAPY", idStr, "weekly", "4942878000") + assert.fieldEquals("RewardAPY", idStr, "monthly", "21183798000") + assert.fieldEquals("RewardAPY", idStr, "yearly", "257736069600") }) })