generated from foundry-rs/forge-template
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* replace magic number with commission denominator variable * handle case where bond is already withdrawn * use signed int math where applicable * do not send eth if amount is 0 * fix math issues * move withdraw logic to withdrawFromProtocol function * remove unnecessary code from withdrawFromProtocol function * implement execution and avs reward tests * run forge fmt * cleanup execution and avs reward cases * create mock eigenpodproxy and quick withdraw test * test bond withdrawn fallback case * only the pod proxy owner can opt into other avs than pufferAVS * fix test for avs rewards to use podproxyowner * run forge fmt * implement verifyAndWithdraw * use send eth transfer method more similar to pool * use new eigenpod interface which exposes validator status * added stub for withdraw slashed eth function * implement initiate withdrawal * Deploy PufferPool to Ephemery * initial upload of create pod account and register script * move pool contract creation to separate function * parse json file as input to script * ignore broadcast folder * output created eigenpodproxy address to file * Add scripts * Add a DeployEverything script that deploys the everything... * add pod provision eth script using new base script * add additional scripts for simulation --------- Co-authored-by: Benjamin <[email protected]> Co-authored-by: JasonVranek <[email protected]>
- Loading branch information
1 parent
6ef4e1d
commit 2562517
Showing
31 changed files
with
3,662 additions
and
126 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
PRIVATE_KEY=deployer private key | ||
PK=deployer private key | ||
EIGEN_POD_MANAGER=eigen pod manager address | ||
EIGEN_SLASHER=eigen slasher address | ||
MAINNET=mainnet rpc url |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,6 @@ | ||
cache/ | ||
out/ | ||
broadcast/ | ||
simulation/ | ||
.env | ||
|
235 changes: 235 additions & 0 deletions
235
broadcast/DeployPuffer.s.sol/39438086/run-1690979192.json
Large diffs are not rendered by default.
Oops, something went wrong.
595 changes: 595 additions & 0 deletions
595
broadcast/DeployPuffer.s.sol/39438086/run-1690979211.json
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"EigenPodProxyImplementation": "0xe30ff99574496ff6d964a15721afc842a56a7df1", | ||
"PoolImplementation": "0x334e282fac9fd244e8dd6b68a74ea7ecd7b8028d", | ||
"EigenPodProxyBeacon": "0xdabf735a41926cee8139ff37491f56ad33ea7d64", | ||
"PufferPool": "0x00cefcd3125e6060a841308330329be418f8356e" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity >=0.8.0 <0.9.0; | ||
|
||
import { Script } from "forge-std/Script.sol"; | ||
import { Strings } from "openzeppelin/utils/Strings.sol"; | ||
import { IPufferPool } from "puffer/interface/IPufferPool.sol"; | ||
import { stdJson } from "forge-std/StdJson.sol"; | ||
|
||
/** | ||
* @title Base Script | ||
* @author Puffer finance | ||
*/ | ||
abstract contract BaseScript is Script { | ||
/** | ||
* @dev Deployer private key is in `PK` env variable | ||
*/ | ||
uint256 _deployerPrivateKey = vm.envUint("PK"); | ||
address internal _broadcaster = vm.addr(_deployerPrivateKey); | ||
|
||
/** | ||
* @dev Reads the deployment file | ||
*/ | ||
string internal _deploymentFilePath = string(abi.encodePacked("deployments/", Strings.toString(block.chainid), "-deployment.json")); | ||
string internal _deploymentData = vm.readFile(_deploymentFilePath); | ||
|
||
/** | ||
* @dev PufferPool deployed on block.chainId | ||
*/ | ||
IPufferPool internal _pufferPool = IPufferPool(stdJson.readAddress(_deploymentData, ".PufferPool")); | ||
|
||
modifier broadcast() { | ||
vm.startBroadcast(_deployerPrivateKey); | ||
_; | ||
vm.stopBroadcast(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity >=0.8.0 <0.9.0; | ||
|
||
import {Script} from "forge-std/Script.sol"; | ||
import {NewBaseScript} from "scripts/NewBaseScript.s.sol"; | ||
import {SafeProxyFactory} from "safe-contracts/proxies/SafeProxyFactory.sol"; | ||
import {Safe} from "safe-contracts/Safe.sol"; | ||
import {IEigenPodProxy} from "puffer/interface/IEigenPodProxy.sol"; | ||
import {IPufferPool} from "puffer/interface/IPufferPool.sol"; | ||
import {BeaconProxy} from "openzeppelin/proxy/beacon/BeaconProxy.sol"; | ||
import {UpgradeableBeacon} from "openzeppelin/proxy/beacon/UpgradeableBeacon.sol"; | ||
import {DeployBeacon} from "scripts/DeployBeacon.s.sol"; | ||
import {EigenPodProxy} from "puffer/EigenPodProxy.sol"; | ||
import {PufferPool} from "puffer/PufferPool.sol"; | ||
import {Test} from "forge-std/Test.sol"; | ||
import {DeploySafe} from "scripts/DeploySafe.s.sol"; | ||
import {DeployPufferPool} from "scripts/DeployPufferPool.s.sol"; | ||
import {Strings} from "openzeppelin/utils/Strings.sol"; | ||
import {CustomJSONBuilder} from "scripts/DeployPuffer.s.sol"; | ||
import "forge-std/console.sol"; | ||
import "forge-std/StdJson.sol"; | ||
|
||
using stdJson for string; | ||
|
||
// Commandline argument will give path to json file for params, and public key, needed in vm.startBroadcast() | ||
// Example script call (Assumes `PK` environment variable is set to eth private key): | ||
// forge script ./CreatePodAccountAndRegisterValidatorKey.s.sol:CreatePodAndRegisterKey ~/puffer/PufferPool/simulation/ephemery-sim-1/validator-1 --sig 'run(string)' --rpc-url 'https://otter.bordel.wtf/erigon' --broadcast | ||
contract CreatePodAndRegisterKey is NewBaseScript { | ||
function _parseRegistrationData( | ||
string memory json | ||
) | ||
internal | ||
returns ( | ||
IPufferPool pool, | ||
address[] memory podAccountOwners, | ||
address podRewardsRecipient, | ||
uint256 podAccountThreshold, | ||
IPufferPool.ValidatorKeyData memory data | ||
) | ||
{ | ||
// Parse out necessary fields | ||
address poolAddress = abi.decode( | ||
vm.parseJson(json, ".poolContract"), | ||
(address) | ||
); | ||
|
||
pool = IPufferPool(poolAddress); | ||
|
||
(podAccountOwners) = abi.decode( | ||
vm.parseJson(json, ".podAccountOwners"), | ||
(address[]) | ||
); | ||
|
||
(podRewardsRecipient) = abi.decode( | ||
vm.parseJson(json, ".podRewardsRecipient"), | ||
(address) | ||
); | ||
|
||
podAccountThreshold = vm.parseJsonUint(json, ".podAccountThreshold"); | ||
|
||
data.blsPubKey = vm.parseJsonBytes(json, ".blsPubKey"); | ||
|
||
data.signature = vm.parseJsonBytes(json, ".signature"); | ||
|
||
data.depositDataRoot = vm.parseJsonBytes32(json, ".depositDataRoot"); | ||
|
||
// For now, don't read blsEncPrivKeyShares from Json, just hardcode empty array (TODO) | ||
bytes[] memory blsEncPrivKeyShares; | ||
data.blsEncPrivKeyShares = blsEncPrivKeyShares; | ||
|
||
data.blsPubKeyShares = vm.parseJsonBytesArray(json, ".blsPubKeyShares"); | ||
|
||
data.blockNumber = vm.parseJsonUint(json, ".blockNumber"); | ||
|
||
// Ignore raveEvidence for now (TODO) | ||
data.raveEvidence = bytes(""); | ||
} | ||
|
||
function run(string calldata jsonDir) external broadcast { | ||
string memory pathToJson = string.concat(jsonDir, "/inputs.json"); | ||
|
||
// Read in Json file | ||
string memory json = vm.readFile(pathToJson); | ||
|
||
( | ||
IPufferPool pool, | ||
address[] memory podAccountOwners, | ||
address podRewardsRecipient, | ||
uint256 podAccountThreshold, | ||
IPufferPool.ValidatorKeyData memory data | ||
) = _parseRegistrationData(json); | ||
|
||
// TODO: Add logic to determine which bond amount to use based on above parsed parameters | ||
// Hardcoded bond amount and podRewardsRecipient | ||
uint256 bondAmount = 16 ether; | ||
|
||
Safe podAccount; | ||
IEigenPodProxy eigenPodProxy; | ||
|
||
console.log(address(pool)); | ||
console.log(podRewardsRecipient); | ||
|
||
(podAccount, eigenPodProxy) = pool | ||
.createPodAccountAndRegisterValidatorKey{value: bondAmount}({ | ||
podAccountOwners: podAccountOwners, | ||
podAccountThreshold: podAccountThreshold, | ||
data: data, | ||
podRewardsRecipient: podRewardsRecipient | ||
}); | ||
|
||
// Write the EigenPodProxy address to be easily consumed by calling bash script | ||
vm.writeFile( | ||
string.concat(jsonDir, "/EigenPodProxy-address"), | ||
Strings.toHexString(address(eigenPodProxy)) | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity >=0.8.0 <0.9.0; | ||
|
||
import { BaseScript } from "scripts/BaseScript.s.sol"; | ||
import { IPufferPool } from "puffer/interface/IPufferPool.sol"; | ||
|
||
/** | ||
* @title Create Eigen Pod Proxy and register validator key script | ||
* @author Puffer finance | ||
* @notice Calls the `createPodAccountAndRegisterValidatorKey` function on PufferPool | ||
* @dev Example on how to run the script | ||
* | ||
* forge script scripts/CreatePodAndRegisterKey.s.sol:CreatePodAndRegisterKey --rpc-url=$EPHEMERY_RPC_URL --broadcast --sig "run(bytes)" -vvvv 0xa091f34f8e90ce7eb0f2ca31a3f12e98dbbdffcae36da273d2fe701b3b14d83a492a4704c0ac4a550308faf0eac6384e | ||
*/ | ||
contract CreatePodAndRegisterKey is BaseScript { | ||
/** | ||
* @param pubKey Is the validator pubKey | ||
*/ | ||
function run(bytes calldata pubKey) external broadcast { | ||
|
||
address[] memory owners = new address[](1); | ||
owners[0] = _broadcaster; | ||
|
||
// Use empty object | ||
IPufferPool.ValidatorKeyData memory validatorData = IPufferPool.ValidatorKeyData({ | ||
blsPubKey: pubKey, | ||
signature: new bytes(0), | ||
depositDataRoot: bytes32(""), | ||
blsEncPrivKeyShares: new bytes[](0), | ||
blsPubKeyShares: new bytes[](0), | ||
blockNumber: block.number, | ||
raveEvidence: new bytes(0) | ||
}); | ||
|
||
// Hardcoded bond amount and podRewardsRecipient | ||
uint256 bondAmount = 16 ether; | ||
|
||
_pufferPool.createPodAccountAndRegisterValidatorKey{value: bondAmount}({podAccountOwners: owners, podAccountThreshold: owners.length, data: validatorData, podRewardsRecipient: _broadcaster}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity >=0.8.0 <0.9.0; | ||
|
||
import {Script} from "forge-std/Script.sol"; | ||
import {NewBaseScript} from "scripts/NewBaseScript.s.sol"; | ||
import {SafeProxyFactory} from "safe-contracts/proxies/SafeProxyFactory.sol"; | ||
import {Safe} from "safe-contracts/Safe.sol"; | ||
import {IEigenPodProxy} from "puffer/interface/IEigenPodProxy.sol"; | ||
import {IPufferPool} from "puffer/interface/IPufferPool.sol"; | ||
import {BeaconProxy} from "openzeppelin/proxy/beacon/BeaconProxy.sol"; | ||
import {UpgradeableBeacon} from "openzeppelin/proxy/beacon/UpgradeableBeacon.sol"; | ||
import {DeployBeacon} from "scripts/DeployBeacon.s.sol"; | ||
import {EigenPodProxy} from "puffer/EigenPodProxy.sol"; | ||
import {PufferPool} from "puffer/PufferPool.sol"; | ||
import {Test} from "forge-std/Test.sol"; | ||
import {DeploySafe} from "scripts/DeploySafe.s.sol"; | ||
import {DeployPufferPool} from "scripts/DeployPufferPool.s.sol"; | ||
import {Strings} from "openzeppelin/utils/Strings.sol"; | ||
import {CustomJSONBuilder} from "scripts/DeployPuffer.s.sol"; | ||
import {IEigenPodManager} from "eigenlayer/interfaces/IEigenPodManager.sol"; | ||
import {EigenPodManagerMock} from "eigenlayer-test/mocks/EigenPodManagerMock.sol"; | ||
import {ISlasher} from "eigenlayer/interfaces/ISlasher.sol"; | ||
import {SlasherMock} from "test/mocks/SlasherMock.sol"; | ||
import {IStrategyManager} from "eigenlayer/interfaces/IStrategyManager.sol"; | ||
import {IDelegationManager} from "eigenlayer/interfaces/IDelegationManager.sol"; | ||
import {ERC1967Proxy} from "openzeppelin/proxy/ERC1967/ERC1967Proxy.sol"; | ||
import "forge-std/console.sol"; | ||
import "forge-std/StdJson.sol"; | ||
|
||
using stdJson for string; | ||
|
||
// Commandline argument will give path to ephemery simulation dir | ||
// Example script call (Assumes `PK` environment variable is set to eth private key): | ||
// forge script ./DeployEverything.s.sol:DeployEverything ./simulation/ephemery-sim-2 --sig 'run(string)' --rpc-url 'https://otter.bordel.wtf/erigon' --broadcast | ||
contract DeployEverything is NewBaseScript { | ||
function run(string calldata simulationDir) external broadcast { | ||
console.log("Running DeployEverything"); | ||
|
||
address eigenPodManager = address(new EigenPodManagerMock()); | ||
// if (!useEigenPodManagerMock) { | ||
// eigenPodManager = 0x91E677b07F7AF907ec9a428aafA9fc14a0d3A338; | ||
// } | ||
|
||
ISlasher slasher = new SlasherMock( | ||
IStrategyManager(address(0)), | ||
IDelegationManager(address(0)) | ||
); | ||
EigenPodProxy eigenPodProxyImplementation = new EigenPodProxy( | ||
IEigenPodManager(eigenPodManager), | ||
slasher | ||
); | ||
|
||
UpgradeableBeacon beacon = new UpgradeableBeacon( | ||
address(eigenPodProxyImplementation) | ||
); | ||
beacon.transferOwnership(_broadcaster); | ||
|
||
// begin DeploySafe | ||
SafeProxyFactory proxyFactory = new SafeProxyFactory(); | ||
|
||
Safe safeImplementation = new Safe(); | ||
|
||
// Deploys Puffer Pool implementation | ||
PufferPool poolImpl = new PufferPool(address(beacon)); | ||
// Deploys Proxy contract | ||
ERC1967Proxy proxy = new ERC1967Proxy(address(poolImpl), ""); | ||
// Casts Proxy to PufferPool | ||
PufferPool pool = PufferPool(payable(address(proxy))); | ||
// Initializes the Pool | ||
address[] memory treasuryOwners = new address[](1); | ||
treasuryOwners[0] = address(_broadcaster); // mock owner | ||
|
||
pool.initialize({ | ||
safeProxyFactory: address(proxyFactory), | ||
safeImplementation: address(safeImplementation), | ||
treasuryOwners: treasuryOwners | ||
}); | ||
|
||
// For test environment transfer ownership to Test contract | ||
pool.transferOwnership(_broadcaster); | ||
|
||
console.log(address(pool)); | ||
|
||
// Write the PufferPool address to be easily consumed by calling bash script | ||
vm.writeFile(string.concat(simulationDir, "/PufferPool-address"), Strings.toHexString(address(pool))); | ||
} | ||
} |
Oops, something went wrong.