Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: integrate rewards #71

Open
wants to merge 37 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
5dc4af7
add rewards
Sidu28 Sep 21, 2024
8d0ecbb
added payments
Sidu28 Sep 24, 2024
07ff1a5
fixed imports
Sidu28 Sep 24, 2024
81d45d9
create payments logic
Sidu28 Sep 25, 2024
cf88e4b
add root creating functions
Sidu28 Sep 25, 2024
847f575
add submitRoot call
Sidu28 Sep 25, 2024
0cca2d3
fixed build
Sidu28 Sep 25, 2024
a7aeffa
switched to keccak
Sidu28 Sep 25, 2024
737b19b
added proof generation
Sidu28 Sep 25, 2024
821e2c7
added json parsing
Sidu28 Sep 25, 2024
50707a1
separate import for SM
Sidu28 Sep 26, 2024
63bed42
added token to deployment data
Sidu28 Sep 26, 2024
868bd41
cleanup/restrucutring
Sidu28 Oct 1, 2024
7cb9606
added lib
Sidu28 Oct 2, 2024
9a6436c
filled in functions
Sidu28 Oct 2, 2024
b48f334
added test file
Sidu28 Oct 2, 2024
d443fef
added basic tests
Sidu28 Oct 2, 2024
7d13f21
add unit tests
Sidu28 Oct 3, 2024
b1591cc
added more tests
Sidu28 Oct 3, 2024
c415cf1
fixed broken test
Sidu28 Oct 4, 2024
bfb127f
add padding
Sidu28 Oct 4, 2024
1be5ff1
changes
Sidu28 Oct 7, 2024
1e131fd
builds
Sidu28 Oct 7, 2024
a23fd2e
tests compile
Sidu28 Oct 7, 2024
4d0c3fc
config errors resolved
Sidu28 Oct 8, 2024
aa6b801
erc20mock error
Sidu28 Oct 8, 2024
848e020
payment submission tests passing
Sidu28 Oct 8, 2024
fec70e4
tests compile but without modifiers in RewardsCoordinator
Sidu28 Oct 9, 2024
8a00776
changes
Sidu28 Oct 9, 2024
157c90d
deleted commented out code
Sidu28 Oct 9, 2024
025cb54
added token approval
Sidu28 Oct 9, 2024
4de9947
fix: library use internal function
stevennevins Oct 9, 2024
3453c19
cleanup
Sidu28 Oct 10, 2024
e3a6c44
fixed build
Sidu28 Oct 10, 2024
63099dc
fixed script
Sidu28 Oct 10, 2024
1cac356
script
Sidu28 Oct 10, 2024
6e72fd5
script
Sidu28 Oct 10, 2024
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
6 changes: 6 additions & 0 deletions contracts/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ docs/

# Dotenv file
.env


# DS_store files
.DS_Store
lib/.DS_Store

66 changes: 66 additions & 0 deletions contracts/mocks/MockStrategy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@eigenlayer/contracts/interfaces/IStrategy.sol";

contract MockStrategy is IStrategy {
IERC20 public override underlyingToken;
uint256 public override totalShares;
mapping(address => uint256) public userShares;
uint256 public constant EXCHANGE_RATE = 1e18; // 1:1 exchange rate for simplicity

constructor(IERC20 _underlyingToken) {
underlyingToken = _underlyingToken;
emit StrategyTokenSet(_underlyingToken, 18); // Assuming 18 decimals for simplicity
}

function deposit(IERC20 token, uint256 amount) external override returns (uint256) {
require(token == underlyingToken, "Invalid token");
uint256 newShares = amount;
totalShares += newShares;
userShares[msg.sender] += newShares;
emit ExchangeRateEmitted(EXCHANGE_RATE);
return newShares;
}

function withdraw(address recipient, IERC20 token, uint256 amountShares) external override {
require(token == underlyingToken, "Invalid token");
require(userShares[msg.sender] >= amountShares, "Insufficient shares");
userShares[msg.sender] -= amountShares;
totalShares -= amountShares;
underlyingToken.transfer(recipient, amountShares);
}

function sharesToUnderlying(uint256 amountShares) external pure override returns (uint256) {
return amountShares;
}

function underlyingToShares(uint256 amountUnderlying) external pure override returns (uint256) {
return amountUnderlying;
}

function userUnderlying(address user) external view override returns (uint256) {
return userShares[user];
}

function shares(address user) external view override returns (uint256) {
return userShares[user];
}

function sharesToUnderlyingView(uint256 amountShares) external pure override returns (uint256) {
return amountShares;
}

function underlyingToSharesView(uint256 amountUnderlying) external pure override returns (uint256) {
return amountUnderlying;
}

function userUnderlyingView(address user) external view override returns (uint256) {
return userShares[user];
}

function explanation() external pure override returns (string memory) {
return "Mock Strategy for testing purposes";
}
}
11 changes: 11 additions & 0 deletions contracts/payments.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"leaves": [
"0x29036a1d92861ffd464a1e285030fad3978a36f953ae33c160e606d2ac746c42",
"0x29036a1d92861ffd464a1e285030fad3978a36f953ae33c160e606d2ac746c42",
"0x29036a1d92861ffd464a1e285030fad3978a36f953ae33c160e606d2ac746c42",
"0x29036a1d92861ffd464a1e285030fad3978a36f953ae33c160e606d2ac746c42"
],
"tokenLeaves": [
"0xf5d87050cb923194fe63c7ed2c45cbc913fa6ecf322f3631149c36d9460b3ad6"
]
}
19 changes: 17 additions & 2 deletions contracts/script/HelloWorldDeployer.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ import {console2} from "forge-std/Test.sol";
import {HelloWorldDeploymentLib} from "./utils/HelloWorldDeploymentLib.sol";
import {CoreDeploymentLib} from "./utils/CoreDeploymentLib.sol";
import {UpgradeableProxyLib} from "./utils/UpgradeableProxyLib.sol";
import {StrategyBase} from "@eigenlayer/contracts/strategies/StrategyBase.sol";
import {ERC20Mock} from "../test/ERC20Mock.sol";
import {TransparentUpgradeableProxy} from
"@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import {StrategyFactory} from "@eigenlayer/contracts/strategies/StrategyFactory.sol";
import {StrategyManager} from "@eigenlayer/contracts/core/StrategyManager.sol";


import {
Quorum,
Expand All @@ -19,18 +26,23 @@ contract HelloWorldDeployer is Script {

address private deployer;
address proxyAdmin;
StrategyBase helloWorldStrategy;
StrategyBase helloWorldStrategyImpl;
CoreDeploymentLib.DeploymentData coreDeployment;
HelloWorldDeploymentLib.DeploymentData helloWorldDeployment;
Quorum internal quorum;

ERC20Mock token;
function setUp() public virtual {
deployer = vm.rememberKey(vm.envUint("PRIVATE_KEY"));
vm.label(deployer, "Deployer");

coreDeployment = CoreDeploymentLib.readDeploymentJson("deployments/core/", block.chainid);

token = new ERC20Mock();
stevennevins marked this conversation as resolved.
Show resolved Hide resolved
IStrategy helloWorldStrategy = StrategyFactory(coreDeployment.strategyFactory).deployNewStrategy(token);

quorum.strategies.push(
StrategyParams({strategy: IStrategy(address(420)), multiplier: 10_000})
StrategyParams({strategy: helloWorldStrategy, multiplier: 10_000})
);
}

Expand All @@ -41,6 +53,8 @@ contract HelloWorldDeployer is Script {
helloWorldDeployment =
HelloWorldDeploymentLib.deployContracts(proxyAdmin, coreDeployment, quorum);

helloWorldDeployment.strategy = address(helloWorldStrategy);
helloWorldDeployment.token = address(token);
vm.stopBroadcast();

verifyDeployment();
Expand All @@ -55,6 +69,7 @@ contract HelloWorldDeployer is Script {
helloWorldDeployment.helloWorldServiceManager != address(0),
"HelloWorldServiceManager address cannot be zero"
);
require(helloWorldDeployment.strategy != address(0), "Strategy address cannot be zero");
require(proxyAdmin != address(0), "ProxyAdmin address cannot be zero");
require(
coreDeployment.delegationManager != address(0),
Expand Down
105 changes: 105 additions & 0 deletions contracts/script/SetupPayments.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import {Script} from "forge-std/Script.sol";
import {HelloWorldDeploymentLib} from "./utils/HelloWorldDeploymentLib.sol";
import {CoreDeploymentLib} from "./utils/CoreDeploymentLib.sol";
import {SetupPaymentsLib} from "./utils/SetupPaymentsLib.sol";
import {IRewardsCoordinator} from "@eigenlayer/contracts/interfaces/IRewardsCoordinator.sol";

contract SetupPayments is Script {
struct PaymentInfo {
address[] earners;
bytes32[] earnerTokenRoots,
address recipient;
uint256 numPayments;
uint256 amountPerPayment;
uint32 duration;
uint32 startTimestamp;
uint32 endTimestamp;
uint256 indexToProve;
}

address private deployer;
CoreDeploymentLib.DeploymentData coreDeployment;
HelloWorldDeploymentLib.DeploymentData helloWorldDeployment;

uint256 constant NUM_TOKEN_EARNINGS = 1;
uint256 constant DURATION = 1 weeks;

function setUp() public {
deployer = vm.rememberKey(vm.envUint("PRIVATE_KEY"));
vm.label(deployer, "Deployer");

coreDeployment = CoreDeploymentLib.readDeploymentJson("deployments/core/", block.chainid);
helloWorldDeployment = HelloWorldDeploymentLib.readDeploymentJson("deployments/hello-world/", block.chainid);
}

function run() external {
vm.startBroadcast(deployer);
IRewardsCoordinator(coreDeployment.rewardsCoordinator).setRewardsUpdater(deployer);
PaymentInfo memory info = abi.decode(vm.parseJson(vm.readFile(filePath)), (PaymentInfo));

createAVSRewardsSubmissions(info.numPayments, info.amountPerPayment, info.duration, info.startTimestamp);
submitPaymentRoot(info.earners, info.endTimestamp, info.numPayments, info.amountPerPayment);

IRewardsCoordinator.EarnerTreeMerkleLeaf memory earnerLeaf = IRewardsCoordinator.EarnerTreeMerkleLeaf({
earner: info.earners[info.indexToProve],
tokenRoot: info.earnerTokenRoots[info.indexToProve],
});
processClaim(SetupPaymentsLib.getFilePath(), info.indexToProve, info.recipient, earnerLeaf);








vm.stopBroadcast();
}


function createAVSRewardsSubmissions(uint256 numPayments, uint256 amountPerPayment, uint32 duration, uint32 startTimestamp) public {
SetupPaymentsLib.createAVSRewardsSubmissions(
IRewardsCoordinator(coreDeployment.rewardsCoordinator),
helloWorldDeployment.strategy,
numPayments,
amountPerPayment,
duration,
startTimestamp
);
}

function processClaim(string memory filePath, uint256 indexToProve, address recipient, IRewardsCoordinator.EarnerTreeMerkleLeaf calldata earnerLeaf) public {
SetupPaymentsLib.processClaim(
IRewardsCoordinator(coreDeployment.rewardsCoordinator),
filePath,
indexToProve,
recipient,
earnerLeaf,
NUM_TOKEN_EARNINGS,
helloWorldDeployment.strategy
);
}

function submitPaymentRoot(address[] calldata earners, uint32 endTimestamp, uint32 numPayments, uint32 amountPerPayment) public {
bytes32[] memory tokenLeaves = SetupPaymentsLib.createTokenLeaves(
IRewardsCoordinator(coreDeployment.rewardsCoordinator),
NUM_TOKEN_EARNINGS,
amountPerPayment,
helloWorldDeployment.strategy
);
IRewardsCoordinator.EarnerTreeMerkleLeaf[] memory earnerLeaves = SetupPaymentsLib.createEarnerLeaves(earners, tokenLeaves);

SetupPaymentsLib.submitRoot(
IRewardsCoordinator(coreDeployment.rewardsCoordinator),
tokenLeaves,
earnerLeaves,
helloWorldDeployment.strategy,
endTimestamp,
numPayments,
NUM_TOKEN_EARNINGS
);
}
}
6 changes: 3 additions & 3 deletions contracts/script/utils/CoreDeploymentLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,11 @@ library CoreDeploymentLib {
);

/// TODO: Get actual values
uint32 CALCULATION_INTERVAL_SECONDS = 10 days;
uint32 MAX_REWARDS_DURATION = 10;
uint32 CALCULATION_INTERVAL_SECONDS = 1 days;
uint32 MAX_REWARDS_DURATION = 1 days;
uint32 MAX_RETROACTIVE_LENGTH = 1;
uint32 MAX_FUTURE_LENGTH = 1;
uint32 GENESIS_REWARDS_TIMESTAMP = 100 days;
uint32 GENESIS_REWARDS_TIMESTAMP = 10 days;
address rewardsCoordinatorImpl = address(
new RewardsCoordinator(
IDelegationManager(result.delegationManager),
Expand Down
10 changes: 8 additions & 2 deletions contracts/script/utils/HelloWorldDeploymentLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ library HelloWorldDeploymentLib {
struct DeploymentData {
address helloWorldServiceManager;
address stakeRegistry;
address strategy;
address token;
}

function deployContracts(
Expand All @@ -43,7 +45,7 @@ library HelloWorldDeploymentLib {
address(new ECDSAStakeRegistry(IDelegationManager(core.delegationManager)));
address helloWorldServiceManagerImpl = address(
new HelloWorldServiceManager(
core.avsDirectory, result.stakeRegistry, core.delegationManager
core.avsDirectory, result.stakeRegistry, core.rewardsCoordinator, core.delegationManager
)
);
// Upgrade contracts
Expand Down Expand Up @@ -136,7 +138,11 @@ library HelloWorldDeploymentLib {
data.stakeRegistry.toHexString(),
'","stakeRegistryImpl":"',
data.stakeRegistry.getImplementation().toHexString(),
'"}'
'","strategy":"',
data.strategy.toHexString(),
'","token":"',
data.token.toHexString(),
'"}'
);
}
}
Loading
Loading