Skip to content

Commit 07a7fcb

Browse files
authored
Remove Defender and Holesky (#2944)
* Remove Defender from the repo * Removed Holesky test chain * More Holesky changes * Skip Sonic strategy fork tests * Fix Base cross chain strategy fork tests * Fix Base Curve AMO fork test
1 parent 4f65bb1 commit 07a7fcb

129 files changed

Lines changed: 178 additions & 23097 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,7 @@ contracts/build/
6363
contracts/dist/
6464
contracts/.localKeyValueStorage
6565
contracts/.localKeyValueStorage.mainnet
66-
contracts/.localKeyValueStorage.holesky
6766
contracts/.localKeyValueStorage.base
68-
contracts/scripts/defender-actions/dist/
69-
70-
contracts/lib/defender-actions/dist/
7167

7268
todo.txt
7369
brownie/env-brownie/
@@ -93,4 +89,4 @@ unit-coverage
9389
.certora_internal
9490

9591
# Possible Agent.md file
96-
AGENTS.md
92+
AGENTS.md

CLAUDE.md

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Origin DeFi's OTokens monorepo containing smart contracts for:
99
- **OETH** (Origin Ether) - an Ethereum liquid staking token
1010
- **OS** (Origin Sonic) - Sonic chain native token
1111

12-
Deployed on Ethereum Mainnet, Base, Arbitrum, Sonic, Plume, Holesky, and Hoodi. All smart contract work happens in the `contracts/` directory.
12+
Deployed on Ethereum Mainnet, Base, Arbitrum, Sonic, Plume, Hoodi, and HyperEVM. All smart contract work happens in the `contracts/` directory.
1313

1414
## Setup
1515

@@ -118,16 +118,11 @@ Key strategies: Aave, Compound, Convex/Curve, Balancer, Morpho, Native Staking (
118118
### Harvesters
119119
`contracts/harvest/` - collect reward tokens from strategies and swap to yield-bearing assets. `Harvester` for OUSD, `OETHHarvester` for OETH, network-specific variants exist.
120120

121-
### Automation (Defender Actions)
122-
`scripts/defender-actions/` - OpenZeppelin Defender automation scripts for:
123-
- `doAccounting` - periodic vault accounting
124-
- `harvest` - automated harvesting
125-
- `sonicRequestWithdrawal` / `sonicClaimWithdrawals` - Sonic staking lifecycle
126-
- `crossChainRelay` - Base ↔ Mainnet CCTP relay
127-
128-
Bundle with: `pnpm rollup -c ./scripts/defender-actions/rollup.config.cjs`
129-
130-
**Scheduled actions (Talos):** distinct from the Defender scripts above — the Talos runner's cron/manual actions live in `contracts/tasks/actions/*.ts`, are scheduled in `contracts/migrations/seed_schedules.sql`, and are catalogued in `contracts/docs/ACTIONS.md`. Update that doc in the same change whenever a scheduled action is added, removed, or its behaviour changes.
121+
### Automation (Talos)
122+
The Talos runner's cron/manual actions live in `contracts/tasks/actions/*.ts`,
123+
are scheduled in `contracts/migrations/seed_schedules.sql`, and are catalogued
124+
in `contracts/docs/ACTIONS.md`. Update that doc in the same change whenever a
125+
scheduled action is added, removed, or its behaviour changes.
131126

132127
### Cross-Chain
133128
- CCTP (Circle) for USDC bridging

contracts/README.md

Lines changed: 9 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,6 @@ When using Hardhat tasks, there are a few options for specifying the wallet to s
248248
1. Primary key
249249
2. AWS KMS signer
250250
3. Impersonate
251-
4. Defender Relayer
252251

253252
### Primary Key
254253

@@ -314,144 +313,10 @@ pnpm hardhat healthcheck --network mainnet
314313

315314
**No Postgres required for local runs.** The library's nonce queue is gated by `process.env.DATABASE_URL`: if unset, the action uses a raw ethers signer with ethers' own nonce handling. The gate is a single `if (!process.env.DATABASE_URL) return null` check at the top of the handler — no DB connection is opened. If you want to opt in locally (e.g., via `docker compose up`), set `DATABASE_URL` and the queue engages; `unset DATABASE_URL` to go back.
316315

317-
Signer construction (KMS via `utils/signersNoHardhat.js`, `DEPLOYER_PK` / `GOVERNOR_PK` fallbacks, `IMPERSONATE`, Defender) stays exactly as described in the sections above. The library only handles the nonce wrap; it does not construct signers here.
318-
319-
### Defender Relayer
320-
321-
Open Zeppelin's [Defender](https://defender.openzeppelin.com/) product has a [Relayer](https://docs.openzeppelin.com/defender/v2/manage/relayers) service that is a managed wallet. It handles the nonce, gas, signing and sending of transactions.
322-
323-
To use a [Relayer](https://defender.openzeppelin.com/v2/#/manage/relayers) account, first log into Defender and create an API key for the account you want to use. Use the generated API key and secret to set the `DEFENDER_API_KEY` and `DEFENDER_API_SECRET` environment variables.
324-
325-
```
326-
export DEFENDER_API_KEY=
327-
export DEFENDER_API_SECRET=
328-
```
329-
330-
Once you have finished sending your transactions, the API key for hte Relayer account should be deleted in Defender and the environment variables unset.
331-
332-
```
333-
unset DEFENDER_API_KEY
334-
unset DEFENDER_API_SECRET
335-
```
336-
337-
### Deploying Defender Actions
338-
339-
Actions are used to run operational jobs are specific times or intervals.
340-
341-
[rollup](https://rollupjs.org/) is used to bundle Actions source code in
342-
[/scripts/defender-actions](./scripts/defender-actions) into a single file that can be uploaded to Defender. The
343-
implementation was based off
344-
[Defender Actions example using Rollup](https://github.com/OpenZeppelin/defender-autotask-examples/tree/master/rollup).
345-
The rollup config is in [/scripts/defender-actions/rollup.config.cjs](./scripts/defender-actions/rollup.config.cjs). The
346-
outputs are written to task specific folders under [/scripts/defender-actions/dist](./scripts/defender-actions/dist/).
347-
348-
The [defender-autotask CLI](https://www.npmjs.com/package/@openzeppelin/defender-autotask-client) is used to upload the
349-
Action code to Defender. For this to work, a Defender Team API key with `Manage Actions` capabilities is needed. This
350-
can be generated by a Defender team admin under the `Manage` tab on the top right of the UI and then `API Keys` on the
351-
left menu. Best to unselect all capabilities except `Manage Actions`.
352-
353-
Save the Defender Team API key and secret to your `.env` file.
354-
355-
```
356-
# Open Zeppelin Defender Team API key
357-
DEFENDER_TEAM_KEY=
358-
DEFENDER_TEAM_SECRET=
359-
```
360-
361-
The following will bundle the Actions code ready for upload.
362-
363-
```
364-
cd contracts
365-
pnpm rollup -c ./scripts/defender-actions/rollup.config.cjs
366-
```
367-
368-
If you get error like the below, you will need to install `@rollup/rollup-darwin-x64`
369-
370-
```
371-
Error: Cannot find module @rollup/rollup-darwin-x64. npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). Please try `npm i` again after removing both package-lock.json and node_modules directory.
372-
```
373-
374-
If you are on Apple Silicon (M1/M2/M3) and you node is emulated x64, then the following will return `x64` rather than `arm64`.
375-
376-
```
377-
node -p "process.arch"
378-
```
379-
380-
If x64, run the following to install the required rollup package.
381-
382-
```
383-
pnpm add -D @rollup/rollup-darwin-x64
384-
```
385-
386-
The following will upload the different Action bundles to Defender.
387-
388-
```sh
389-
cd contracts
390-
pnpm rollup -c ./scripts/defender-actions/rollup.config.cjs
391-
392-
# Set the DEFENDER_TEAM_KEY and DEFENDER_TEAM_SECRET environment variables in the .env file
393-
394-
# Set the DEBUG environment variable to oeth* for the Defender Action
395-
pnpm hardhat setActionVars --id e2929f53-db56-49b2-b054-35f7df7fc4fb
396-
pnpm hardhat setActionVars --id 6e4f764d-4126-45a5-b7d9-1ab90cd3ffd6
397-
pnpm hardhat setActionVars --id 84988850-6816-4074-8e7b-c11cb2b32e7e
398-
pnpm hardhat setActionVars --id f92ea662-fc34-433b-8beb-b34e9ab74685
399-
pnpm hardhat setActionVars --id b1d831f1-29d4-4943-bb2e-8e625b76e82c
400-
pnpm hardhat setActionVars --id 6567d7c6-7ec7-44bd-b95b-470dd1ff780b
401-
pnpm hardhat setActionVars --id 6a633bb0-aff8-4b37-aaae-b4c6f244ed87
402-
pnpm hardhat setActionVars --id 076c59e4-4150-42c7-9ba0-9962069ac353
403-
pnpm hardhat setActionVars --id ca80b55c-f3f7-4e03-a2f5-ea444645f8d9
404-
pnpm hardhat setActionVars --id f74f24b4-d98b-4181-89cc-6608369b6f91
405-
pnpm hardhat setActionVars --id aa194c13-0dbf-49d2-8e87-70e61f3d71a8
406-
pnpm hardhat setActionVars --id 65b53496-e426-4850-8349-059e63eb2120
407-
pnpm hardhat setActionVars --id a4f8ca5f-7144-469b-b84a-58b30fed72ce
408-
pnpm hardhat setActionVars --id cbddb98e-a0f6-4aa8-bd73-20aa8e81d704
409-
410-
# Mainnet
411-
pnpm hardhat updateAction --id e2929f53-db56-49b2-b054-35f7df7fc4fb --file doAccounting
412-
pnpm hardhat updateAction --id 6e4f764d-4126-45a5-b7d9-1ab90cd3ffd6 --file harvest
413-
pnpm hardhat updateAction --id 84988850-6816-4074-8e7b-c11cb2b32e7e --file sonicRequestWithdrawal
414-
pnpm hardhat updateAction --id f92ea662-fc34-433b-8beb-b34e9ab74685 --file sonicClaimWithdrawals
415-
pnpm hardhat updateAction --id b1d831f1-29d4-4943-bb2e-8e625b76e82c --file claimBribes
416-
pnpm hardhat updateAction --id 6567d7c6-7ec7-44bd-b95b-470dd1ff780b --file manageBribeOnSonic
417-
pnpm hardhat updateAction --id 6a633bb0-aff8-4b37-aaae-b4c6f244ed87 --file managePassThrough
418-
pnpm hardhat updateAction --id 076c59e4-4150-42c7-9ba0-9962069ac353 --file manageBribes
419-
pnpm hardhat updateAction --id ca80b55c-f3f7-4e03-a2f5-ea444645f8d9 --file ousdRebalancer
420-
pnpm hardhat updateAction --id f74f24b4-d98b-4181-89cc-6608369b6f91 --file updateVotemarketEpochs
421-
pnpm hardhat updateAction --id aa194c13-0dbf-49d2-8e87-70e61f3d71a8 --file manageMerklBribes # Mainnet
422-
pnpm hardhat updateAction --id 65b53496-e426-4850-8349-059e63eb2120 --file manageMerklBribes # Base
423-
pnpm hardhat updateAction --id a4f8ca5f-7144-469b-b84a-58b30fed72ce --file claimSSVRewards
424-
425-
# These are Base -> Mainnet & Mainnet -> Base actions
426-
# they share the codebase. The direction of relaying attestations is defined by the
427-
# network of the relayer that is attached to the action
428-
pnpm hardhat updateAction --id bb43e5da-f936-4185-84da-253394583665 --file crossChainRelay
429-
pnpm hardhat updateAction --id e571409b-5399-48e4-bfb2-50b7af9903aa --file crossChainRelay
430-
431-
# One-off action for backfilling a missing tx-level key in Defender KV store
432-
pnpm hardhat updateAction --id cbddb98e-a0f6-4aa8-bd73-20aa8e81d704 --file crossChainRelayBackfillTx
433-
434-
# OUSD Ethereum -> HyperEVM actions
435-
pnpm hardhat updateAction --id 0b852456-96a0-4f1d-9d6c-39e1c6ae9dfc --file crossChainRelayHyperEVM
436-
pnpm hardhat updateAction --id 65f04f74-8da7-4fc5-94b3-96be31bac03b --file crossChainRelayHyperEVM
437-
438-
```
439-
440-
To backfill a missing tx-level cross-chain relay key, set
441-
`HARDCODED_TRANSACTION_ID` and `HARDCODED_DESTINATION_CHAIN_ID` in
442-
`scripts/defender-actions/crossChainRelayBackfillTx.js`, then bundle/upload and
443-
run the `crossChainRelayBackfillTx` Action manually in Defender.
444-
445-
This stores both tx-level keys with value `processed` in Defender's key-value
446-
store:
447-
448-
- `cctp_message_<HARDCODED_TRANSACTION_ID>` (legacy format)
449-
- `cctp_message_<HARDCODED_TRANSACTION_ID>_<cctpDestinationDomainId>` (current
450-
format from `tasks/crossChain.js`, where domain id is derived from the
451-
hardcoded destination chain id: mainnet `1 -> 0`, base `8453 -> 6`, hyperevm
452-
`999 -> 19`)
453-
454-
`rollup` can be installed globally to avoid the `npx` prefix.
316+
Signer construction (KMS via `utils/signersNoHardhat.js`, `DEPLOYER_PK` /
317+
`GOVERNOR_PK` fallbacks, and `IMPERSONATE`) stays exactly as described in the
318+
sections above. The library only handles the nonce wrap; it does not construct
319+
signers here.
455320

456321
### Encrypting / decrypting validator private keys
457322

@@ -470,7 +335,11 @@ The process is as follows:
470335

471336
#### Storing encrypted validator private keys
472337

473-
Defender Action that operates the validators will by default request a validator with encrypted private keys and store those encrypted keys in the `validator-keys` S3 bucket. Each validator private key is one S3 object and the name of the object is the pubkey (schema: [pubkey].json) of the validator. The S3 bucket has versioning enabled so we can always retrieve possibly overwritten / deleted objects.
338+
The validator automation requests validators with encrypted private keys and
339+
stores those encrypted keys in the `validator-keys` S3 bucket. Each validator
340+
private key is one S3 object and the name of the object is the pubkey (schema:
341+
`[pubkey].json`). The S3 bucket has versioning enabled so overwritten or deleted
342+
objects can be recovered.
474343

475344
#### Storing the master private key
476345

contracts/contracts/automation/AutoWithdrawalModule.sol

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { IStrategy } from "../interfaces/IStrategy.sol";
1616
* 1. Deploy this module
1717
* 2. Call `safe.enableModule(address(this))` to authorize it
1818
*
19-
* An off-chain operator (e.g. Defender Relayer) calls `fundWithdrawals()`
19+
* An off-chain operator calls `fundWithdrawals()`
2020
* periodically. The module:
2121
* - First tries to satisfy the queue from idle vault funds
2222
* - If there's still a shortfall, withdraws the exact shortfall amount
@@ -66,7 +66,7 @@ contract AutoWithdrawalModule is AbstractSafeModule {
6666

6767
/**
6868
* @param _safeContract Address of the Gnosis Safe (Guardian multisig).
69-
* @param _operator Address of the off-chain operator (e.g. Defender relayer).
69+
* @param _operator Address of the off-chain operator.
7070
* @param _vault Address of the OUSD/OETH vault.
7171
* @param _strategy Initial strategy to pull liquidity from.
7272
*/
@@ -91,7 +91,7 @@ contract AutoWithdrawalModule is AbstractSafeModule {
9191

9292
/**
9393
* @notice Fund the vault's withdrawal queue from the configured strategy.
94-
* Called periodically by an off-chain operator (Defender Actions).
94+
* Called periodically by an off-chain operator.
9595
*
9696
* Steps:
9797
* 1. Ask the vault to absorb any idle asset it already holds.
@@ -100,7 +100,7 @@ contract AutoWithdrawalModule is AbstractSafeModule {
100100
*
101101
* This function never reverts on "soft" failures (strategy underfunded,
102102
* Safe exec failure). It emits a descriptive event instead so off-chain
103-
* monitoring can alert the team without breaking the Defender action.
103+
* monitoring can alert the team without breaking the automation action.
104104
*/
105105
function fundWithdrawals() external onlyOperator {
106106
// Step 1: Let the vault absorb any asset it already holds idle.

contracts/contracts/automation/RebalancerModule.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { VaultStorage } from "../vault/VaultStorage.sol";
1616
* 1. Deploy this module
1717
* 2. Call `safe.enableModule(address(this))` to authorize it
1818
*
19-
* An off-chain operator (e.g. Defender Action) calls
19+
* An off-chain operator calls
2020
* `processWithdrawalsAndDeposits` periodically with computed strategy/amount
2121
* arrays. Either array may be empty. All intelligence (APY fetching, target
2222
* allocation, constraint enforcement) lives off-chain. This contract is a
@@ -87,7 +87,7 @@ contract RebalancerModule is AbstractSafeModule {
8787

8888
/**
8989
* @param _safeContract Address of the Gnosis Safe (Guardian multisig).
90-
* @param _operator Address of the off-chain operator (e.g. Defender relayer).
90+
* @param _operator Address of the off-chain operator.
9191
* @param _vault Address of the OUSD vault.
9292
*/
9393
constructor(

contracts/contracts/strategies/NativeStaking/ValidatorAccountant.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ abstract contract ValidatorAccountant is ValidatorRegistrator {
9191
/// the accounting function will treat that as a validator slashing.
9292
/// @notice Perform the accounting attributing beacon chain ETH to either full or partial withdrawals. Returns true when
9393
/// accounting is valid and fuse isn't "blown". Returns false when fuse is blown.
94-
/// @dev This function could in theory be permission-less but lets allow only the Registrator (Defender Action) to call it
94+
/// @dev This function could in theory be permission-less but only the automation registrator can call it
9595
/// for now.
9696
/// @return accountingValid true if accounting was successful, false if fuse is blown
9797
/* solhint-enable max-line-length */

contracts/deploy/deployActions.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ const {
2323
const { replaceContractAt } = require("../utils/hardhat");
2424
const { resolveContract } = require("../utils/resolvers");
2525
const { impersonateAccount, getSigner } = require("../utils/signers");
26-
const { getDefenderSigner } = require("../utils/signersNoHardhat");
2726
const { sleep } = require("../utils/time");
2827
const { getTxOpts } = require("../utils/tx");
2928
const createxAbi = require("../abi/createx.json");
@@ -199,7 +198,7 @@ const upgradeNativeStakingSSVStrategy = async () => {
199198

200199
const networkName = await getNetworkName();
201200
if (networkName == "hoodi") {
202-
const sGovernor = isFork ? await getSigner() : await getDefenderSigner();
201+
const sGovernor = await getSigner();
203202
await withConfirmation(
204203
strategyProxy.connect(sGovernor).upgradeTo(dStrategyImpl.address)
205204
);
@@ -232,7 +231,7 @@ const upgradeCompoundingStakingSSVStrategy = async () => {
232231
]
233232
);
234233

235-
const sDeployer = isFork ? await getSigner() : await getDefenderSigner();
234+
const sDeployer = await getSigner();
236235
await withConfirmation(
237236
strategyProxy.connect(sDeployer).upgradeTo(dStrategyImpl.address)
238237
);
@@ -390,7 +389,7 @@ const deployCompoundingStakingSSVStrategy = async () => {
390389
const cBeaconProofs = await ethers.getContract("BeaconProofs");
391390

392391
let governorAddress;
393-
// Deploy the proxy on Hoodi fork not as defender relayer since we will not
392+
// Deploy the proxy on a Hoodi fork with the local signer since we will not
394393
// test SSV token claiming on that testnet
395394
if ((isTest && !isFork) || networkName == "hoodi") {
396395
// For unit tests and Hoodi, use the Governor contract
@@ -425,7 +424,7 @@ const deployCompoundingStakingSSVStrategy = async () => {
425424
);
426425
} else {
427426
// For fork tests, mainnet and Hoodi deployments.
428-
// Should have already been deployed by the Defender Relayer as SSV rewards are sent to the deployer.
427+
// Should already be deployed by the production signer because SSV rewards are sent to the deployer.
429428
// Use the deployStakingProxy Hardhat task to deploy
430429
cCompoundingStakingSSVStrategyProxy = await ethers.getContract(
431430
"CompoundingStakingSSVStrategyProxy"
@@ -447,7 +446,7 @@ const deployCompoundingStakingSSVStrategy = async () => {
447446
cCompoundingStakingSSVStrategyProxy.connect(sDeployer).claimGovernance()
448447
);
449448
} else {
450-
/* Before kicking off the deploy script make sure the Defender relayer transfers the governance
449+
/* Before kicking off the deploy script make sure the production signer transfers governance
451450
* of the proxy to the deployer account that shall be deploying this script so it will be able
452451
* to initialize the proxy contract
453452
*

0 commit comments

Comments
 (0)