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
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ function totalAssets() public view virtual returns (uint256);
function asset() external view virtual returns (address);
```

## Lending Platforms

The ARM token can be used as collateral on lending platforms to borrow other assets. The ARM token can not be borrowed on lending platforms as the ARM's price, or assets per share, can be increased by donating assets to the ARM. eg donating WETH or stETH to the Lido ARM will increase the ARM's token price. Increasing the price of a borrowed asset increases the borrower's loan to value (LTV) ratio which can lead to a liquidation.

## Development

### Install
Expand Down
86 changes: 43 additions & 43 deletions build/deployments-1.json
Original file line number Diff line number Diff line change
@@ -1,44 +1,44 @@
{
"executions": {
"001_CoreMainnet": 1723685111,
"002_UpgradeMainnet": 1726812322,
"003_UpgradeLidoARMScript": 1729073099,
"004_UpdateCrossPriceScript": 1739872139,
"005_RegisterLidoWithdrawalsScript": 1743500783,
"006_ChangeFeeCollector": 1751894483,
"007_UpgradeLidoARMMorphoScript": 1754407511,
"008_DeployPendleAdaptor": 1755770279,
"009_UpgradeLidoARMSetBufferScript": 1755692363,
"010_UpgradeLidoARMAssetScript": 1764755147,
"011_DeployEtherFiARMScript": 1761812927,
"012_UpgradeEtherFiARMScript": 1763557643,
"013_UpgradeOETHARMScript": 1765353347,
"014_DeployEthenaARMScript": 1764664655
},
"contracts": {
"ARM_ZAPPER": "0xE11EDbd5AE4Fa434Af7f8D7F03Da1742996e7Ab2",
"ETHENA_ARM": "0xCEDa2d856238aA0D12f6329de20B9115f07C366d",
"ETHENA_ARM_CAP_IMPL": "0x7073F39ae371962C2469D72f01f907375bB11E08",
"ETHENA_ARM_CAP_MAN": "0x687AFB5A52A15122fD5FC54A8B52cfd58346fb0C",
"ETHENA_ARM_IMPL": "0x6c181f2CA4224e42Cee8Fc7199c060261AD55d7d",
"ETHERFI_ARM_IMPL": "0x69b98667134EeE3eBF75799dacBCd604E28709ab",
"ETHER_FI_ARM": "0xfB0A3CF9B019BFd8827443d131b235B3E0FC58d2",
"ETHER_FI_ARM_CAP_IMPL": "0xe27720Fc3f3707D47015e274D81a99e5B0800472",
"ETHER_FI_ARM_CAP_MAN": "0xf2A18F7330141Ec737EB73A0A5Ea8E4d7e9bE7ec",
"ETHER_FI_ARM_IMPL": "0x00B53CEE151c043CBe4bbFe4cfD2938Cb4fabCEB",
"LIDO_ARM": "0x85B78AcA6Deae198fBF201c82DAF6Ca21942acc6",
"LIDO_ARM_CAP_IMPL": "0x8506486813d025C5935dF481E450e27D2e483dc9",
"LIDO_ARM_CAP_MAN": "0xf54ebff575f699d281645c6F14Fe427dFFE629CF",
"LIDO_ARM_IMPL": "0xC0297a0E39031F09406F0987C9D9D41c5dfbc3df",
"LIDO_ARM_ZAPPER": "0x01F30B7358Ba51f637d1aa05D9b4A60f76DAD680",
"MORPHO_MARKET_ETHERFI": "0x8Cf42b82fFFa3E7714D62a2cA223acBeC1Eef095",
"MORPHO_MARKET_ETHERFI_IMPL": "0x2a1b59870f7806E60dF58415B0C220C096f57658",
"MORPHO_MARKET_MEVCAPITAL": "0x29c4Bb7B1eBcc53e8CBd16480B5bAe52C69806D3",
"MORPHO_MARKET_MEVCAPITAL_IMP": "0x90c7ABC962f96de171ee395A242D2Ff794D0a04c",
"MORPHO_MARKET_ORIGIN": "0x0ad39D67404aE36Fe476eFDDE1306a5414383544",
"MORPHO_MARKET_ORIGIN_IMPL": "0x2ea9D1827973813D77aA8f35BD23cb1F1311A648",
"OETH_ARM": "0x6bac785889A4127dB0e0CeFEE88E0a9F1Aaf3cC7",
"OETH_ARM_IMPL": "0x9A2be51E45Eec98F75b3e6e1b334246c94663641",
"PENDLE_ORIGIN_ARM_SY": "0xbcae2Eb1cc47F137D8B2D351B0E0ea8DdA4C6184"
}
}
"executions": {
"001_CoreMainnet": 1723685111,
"002_UpgradeMainnet": 1726812322,
"003_UpgradeLidoARMScript": 1729073099,
"004_UpdateCrossPriceScript": 1739872139,
"005_RegisterLidoWithdrawalsScript": 1743500783,
"006_ChangeFeeCollector": 1751894483,
"007_UpgradeLidoARMMorphoScript": 1754407511,
"008_DeployPendleAdaptor": 1755770279,
"009_UpgradeLidoARMSetBufferScript": 1755692363,
"010_UpgradeLidoARMAssetScript": 1764755147,
"011_DeployEtherFiARMScript": 1761812927,
"012_UpgradeEtherFiARMScript": 1763557643,
"013_UpgradeOETHARMScript": 1765353347,
"014_DeployEthenaARMScript": 1764664655
},
"contracts": {
"ARM_ZAPPER": "0xE11EDbd5AE4Fa434Af7f8D7F03Da1742996e7Ab2",
"ETHENA_ARM": "0xCEDa2d856238aA0D12f6329de20B9115f07C366d",
"ETHENA_ARM_CAP_IMPL": "0x7073F39ae371962C2469D72f01f907375bB11E08",
"ETHENA_ARM_CAP_MAN": "0x687AFB5A52A15122fD5FC54A8B52cfd58346fb0C",
"ETHENA_ARM_IMPL": "0x6c181f2CA4224e42Cee8Fc7199c060261AD55d7d",
"ETHERFI_ARM_IMPL": "0x69b98667134EeE3eBF75799dacBCd604E28709ab",
"ETHER_FI_ARM": "0xfB0A3CF9B019BFd8827443d131b235B3E0FC58d2",
"ETHER_FI_ARM_CAP_IMPL": "0xe27720Fc3f3707D47015e274D81a99e5B0800472",
"ETHER_FI_ARM_CAP_MAN": "0xf2A18F7330141Ec737EB73A0A5Ea8E4d7e9bE7ec",
"ETHER_FI_ARM_IMPL": "0x00B53CEE151c043CBe4bbFe4cfD2938Cb4fabCEB",
"LIDO_ARM": "0x85B78AcA6Deae198fBF201c82DAF6Ca21942acc6",
"LIDO_ARM_CAP_IMPL": "0x8506486813d025C5935dF481E450e27D2e483dc9",
"LIDO_ARM_CAP_MAN": "0xf54ebff575f699d281645c6F14Fe427dFFE629CF",
"LIDO_ARM_IMPL": "0xC0297a0E39031F09406F0987C9D9D41c5dfbc3df",
"LIDO_ARM_ZAPPER": "0x01F30B7358Ba51f637d1aa05D9b4A60f76DAD680",
"MORPHO_MARKET_ETHERFI": "0x8Cf42b82fFFa3E7714D62a2cA223acBeC1Eef095",
"MORPHO_MARKET_ETHERFI_IMPL": "0x2a1b59870f7806E60dF58415B0C220C096f57658",
"MORPHO_MARKET_MEVCAPITAL": "0x29c4Bb7B1eBcc53e8CBd16480B5bAe52C69806D3",
"MORPHO_MARKET_MEVCAPITAL_IMP": "0x90c7ABC962f96de171ee395A242D2Ff794D0a04c",
"MORPHO_MARKET_ORIGIN": "0x0ad39D67404aE36Fe476eFDDE1306a5414383544",
"MORPHO_MARKET_ORIGIN_IMPL": "0x2ea9D1827973813D77aA8f35BD23cb1F1311A648",
"ORIGIN_ARM": "0x6bac785889A4127dB0e0CeFEE88E0a9F1Aaf3cC7",
"ORIGIN_ARM_IMPL": "0x9A2be51E45Eec98F75b3e6e1b334246c94663641",
"PENDLE_ORIGIN_ARM_SY": "0xbcae2Eb1cc47F137D8B2D351B0E0ea8DdA4C6184"
}
}
33 changes: 33 additions & 0 deletions src/js/actions/allocateOETH.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const { Defender } = require("@openzeppelin/defender-sdk");
const { ethers } = require("ethers");

const { allocate } = require("../tasks/admin");
const { mainnet } = require("../utils/addresses");
const armAbi = require("../../abis/OriginARM.json");

// Entrypoint for the Defender Action
const handler = async (event) => {
// Initialize defender relayer provider and signer
const client = new Defender(event);
const provider = client.relaySigner.getProvider({ ethersVersion: "v6" });
const signer = await client.relaySigner.getSigner(provider, {
speed: "fastest",
ethersVersion: "v6",
});

console.log(
`DEBUG env var in handler before being set: "${process.env.DEBUG}"`,
);

// References to contracts
const arm = new ethers.Contract(mainnet.OethARM, armAbi, signer);

await allocate({
signer,
arm,
threshold: 10000,
maxGasPrice: 500,
});
};

module.exports = { handler };
2 changes: 1 addition & 1 deletion src/js/actions/autoClaimWithdraw.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const { Defender } = require("@openzeppelin/defender-sdk");
const { ethers } = require("ethers");

const { autoClaimWithdraw } = require("../tasks/liquidity");
const { autoClaimWithdraw } = require("../tasks/liquidityAutomation");
const { mainnet } = require("../utils/addresses");
const erc20Abi = require("../../abis/ERC20.json");
const oethARMAbi = require("../../abis/OethARM.json");
Expand Down
8 changes: 4 additions & 4 deletions src/js/actions/autoRequestWithdraw.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const { Defender } = require("@openzeppelin/defender-sdk");
const { ethers } = require("ethers");

const { autoRequestWithdraw } = require("../tasks/liquidity");
const { autoRequestWithdraw } = require("../tasks/liquidityAutomation");
const { mainnet } = require("../utils/addresses");
const erc20Abi = require("../../abis/ERC20.json");
const oethARMAbi = require("../../abis/OethARM.json");
Expand All @@ -21,14 +21,14 @@ const handler = async (event) => {
);

// References to contracts
const asset = new ethers.Contract(mainnet.OETHProxy, erc20Abi, signer);
const baseAsset = new ethers.Contract(mainnet.OETHProxy, erc20Abi, signer);
const arm = new ethers.Contract(mainnet.OethARM, oethARMAbi, signer);

await autoRequestWithdraw({
signer,
asset,
baseAsset,
arm,
minAmount: 1,
minAmount: 5,
confirm: true,
});
};
Expand Down
4 changes: 2 additions & 2 deletions src/js/actions/collectEtherFiFees.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const { ethers } = require("ethers");

const { collectFees } = require("../tasks/admin");
const { mainnet } = require("../utils/addresses");
const etherFiARMAbi = require("../../abis/EtherFiARM.json");
const armAbi = require("../../abis/EtherFiARM.json");

// Entrypoint for the Defender Action
const handler = async (event) => {
Expand All @@ -20,7 +20,7 @@ const handler = async (event) => {
);

// References to contracts
const arm = new ethers.Contract(mainnet.etherfiARM, etherFiARMAbi, signer);
const arm = new ethers.Contract(mainnet.etherfiARM, armAbi, signer);

await collectFees({
signer,
Expand Down
31 changes: 31 additions & 0 deletions src/js/actions/collectOETHFees.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const { Defender } = require("@openzeppelin/defender-sdk");
const { ethers } = require("ethers");

const { collectFees } = require("../tasks/admin");
const { mainnet } = require("../utils/addresses");
const armAbi = require("../../abis/OriginARM.json");

// Entrypoint for the Defender Action
const handler = async (event) => {
// Initialize defender relayer provider and signer
const client = new Defender(event);
const provider = client.relaySigner.getProvider({ ethersVersion: "v6" });
const signer = await client.relaySigner.getSigner(provider, {
speed: "fastest",
ethersVersion: "v6",
});

console.log(
`DEBUG env var in handler before being set: "${process.env.DEBUG}"`,
);

// References to contracts
const arm = new ethers.Contract(mainnet.OethARM, armAbi, signer);

await collectFees({
signer,
arm,
});
};

module.exports = { handler };
11 changes: 7 additions & 4 deletions src/js/actions/rollup.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,17 @@ const actions = [
"collectFeesSonic",
"collectEtherFiFees",
"collectEthenaFees",
"allocateSonic",
"collectOETHFees",
"collectRewardsSonic",
"setPrices",
"setPricesEtherFi",
"setOSSiloPriceAction",
"allocateLido",
"allocateEtherFi",
"allocateEthena",
"allocateOETH",
"allocateSonic",
"setOSSiloPriceAction",
"setPrices",
"setPricesEtherFi",
"setPricesOETH",
];

module.exports = actions.map((action) => ({
Expand Down
50 changes: 50 additions & 0 deletions src/js/actions/setPricesOETH.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const { Defender } = require("@openzeppelin/defender-sdk");
const { ethers } = require("ethers");

const { setPrices } = require("../tasks/lidoMorphoPrices");
const { mainnet } = require("../utils/addresses");
const armAbi = require("../../abis/OriginARM.json");

// Entrypoint for the Defender Action
const handler = async (event) => {
// Initialize defender relayer provider and signer
const client = new Defender(event);
const provider = client.relaySigner.getProvider({ ethersVersion: "v6" });
const signer = await client.relaySigner.getSigner(provider, {
speed: "fastest",
ethersVersion: "v6",
});

console.log(
`DEBUG env var in handler before being set: "${process.env.DEBUG}"`,
);

// References to contracts
const arm = new ethers.Contract(mainnet.etherfiARM, armAbi, signer);

try {
await setPrices({
signer,
arm,
// sellPrice: 0.9998,
// buyPrice: 0.9997,
maxSellPrice: 0.9999,
minSellPrice: 0.9995,
maxBuyPrice: 0.9995,
minBuyPrice: 0.996,
// inch: true,
// curve: true,
kyber: true,
amount: 10,
tolerance: 0.3,
fee: 5,
offset: 1.0,
priceOffset: true,
blockTag: "latest",
});
} catch (error) {
console.error(error);
}
};

module.exports = { handler };
24 changes: 9 additions & 15 deletions src/js/tasks/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ async function allocate({
}

// 1. Call the allocate static call to get the return values
// Returned value can be either a single int256 or a tuple of two int256 values
// Returned value is a tuple of two int256 values
let liquidityDelta;
[, liquidityDelta] = await arm.allocate.staticCall();

Expand All @@ -60,21 +60,14 @@ async function allocate({
if (activeMarketAddress !== ethers.ZeroAddress) {
const activeMarket = new ethers.Contract(
activeMarketAddress,
["function market() external view returns (address)"],
signer,
);

// Get the underlying ERC-4626 vault. eg Silo or Morpho Vault
const underlyingVaultAddress = await activeMarket.market();
const underlyingVault = new ethers.Contract(
underlyingVaultAddress,
["function maxWithdraw(address) external view returns (uint256)"],
signer,
);

// Check there is liquidity available to withdraw from the lending market
const availableAssets =
await underlyingVault.maxWithdraw(activeMarketAddress);
const availableAssets = await activeMarket.maxWithdraw(
await arm.getAddress(),
);
if (availableAssets < parseUnits("0.01", 18)) {
log(
`Only ${formatUnits(availableAssets)} liquidity available in the active lending market, skipping allocation`,
Expand All @@ -84,16 +77,17 @@ async function allocate({
}
}

// Add 10% buffer to gas limit
let gasLimit = await arm.connect(signer).allocate.estimateGas();
gasLimit = (gasLimit * 11n) / 10n;

log(
`About to allocate ${formatUnits(
liquidityDelta,
)} to/from the active lending market`,
);

if (execute) {
// Add 10% buffer to gas limit
let gasLimit = await arm.connect(signer).allocate.estimateGas();
gasLimit = (gasLimit * 11n) / 10n;

const tx = await arm.connect(signer).allocate({ gasLimit });
await logTxDetails(tx, "allocate");
}
Expand Down
8 changes: 7 additions & 1 deletion src/js/tasks/lido.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const {
} = require("./markets");
const { getBlock } = require("../utils/block");
const { getLidoQueueData } = require("../utils/lido");
const { getMerklRewards } = require("../utils/merkl");
const { getSigner } = require("../utils/signers");
const { logTxDetails } = require("../utils/txLogger");
const {
Expand Down Expand Up @@ -226,7 +227,7 @@ const logAssets = async (arm, blockTag) => {
let lendingMarketBalance = 0n;
// Get the lending market from the active market
// Atm we use a hardcoded address, but this should be replaced with a call to the active market once the ARM is upgraded
let marketAddress = "0x29c4Bb7B1eBcc53e8CBd16480B5bAe52C69806D3"; //await arm.activeMarket({ blockTag });
let marketAddress = await arm.activeMarket({ blockTag });
if (marketAddress != addresses.zero) {
const marketContract = await ethers.getContractAt(
"Abstract4626MarketWrapper",
Expand Down Expand Up @@ -269,6 +270,10 @@ const logAssets = async (arm, blockTag) => {
const buffer = await arm.armBuffer({ blockTag });
const bufferPercent = (buffer * 10000n) / parseUnits("1");

const { amount: morphoRewards } = await getMerklRewards({
userAddress: marketAddress,
});

console.log(`Assets`);
console.log(`liquidity buffer ${formatUnits(bufferPercent, 2)}%`);
console.log(
Expand Down Expand Up @@ -303,6 +308,7 @@ const logAssets = async (arm, blockTag) => {
console.log(
`${formatUnits(wethInStrategist, 18).padEnd(24)} WETH in Strategist (fees)`,
);
console.log(`${formatUnits(morphoRewards, 18)} MORPHO rewards claimable`);

return { totalAssets, totalSupply, liquidityWeth };
};
Expand Down
Loading
Loading