Skip to content

Commit

Permalink
Rebalance a change gracefully when previous total stake is zero (skip…
Browse files Browse the repository at this point in the history
… deploy)
  • Loading branch information
shanejearley committed Oct 30, 2023
1 parent f38be56 commit 3b79d03
Show file tree
Hide file tree
Showing 15 changed files with 1,955 additions and 269 deletions.
2 changes: 1 addition & 1 deletion common/env/src/mock/validators.json

Large diffs are not rendered by default.

489 changes: 478 additions & 11 deletions contracts/ethereum/.openzeppelin/goerli.json

Large diffs are not rendered by default.

6 changes: 0 additions & 6 deletions contracts/ethereum/helpers/upkeep.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,12 @@ export async function fulfillReport({
response: balancesResponse
})

console.log(ethers.utils.defaultAbiCoder.encode(['uint32'], [activatedDeposits]))
console.log(ethers.utils.defaultAbiCoder.encode(['uint32'], [forcedExits]))
console.log(ethers.utils.defaultAbiCoder.encode(['uint32'], [completedExits]))
console.log(ethers.utils.defaultAbiCoder.encode(['uint32[5]'], [compoundablePoolIds]))

const detailsRequestId = requestIds[1]
const detailsResponse = ethers.utils.defaultAbiCoder.encode(
['uint32', 'uint32', 'uint32', 'uint32[5]'],
[activatedDeposits, forcedExits, completedExits, compoundablePoolIds]
)

console.log('DETAILS', JSON.stringify({ detailsRequestId, detailsResponse }))
await fulfillFunctionsRequest({
donTransmitter,
functionsBillingRegistry,
Expand Down
84 changes: 46 additions & 38 deletions contracts/ethereum/src/v1/CasimirManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,13 @@ import "@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolState.sol";
import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol";

/// @title Manager that accepts and distributes deposits
contract CasimirManager is ICasimirManager, CasimirCore, Initializable, OwnableUpgradeable, ReentrancyGuardUpgradeable {
contract CasimirManager is
ICasimirManager,
CasimirCore,
Initializable,
OwnableUpgradeable,
ReentrancyGuardUpgradeable
{
using CasimirArray for uint32[];
using CasimirArray for bytes[];
using CasimirArray for Withdrawal[];
Expand Down Expand Up @@ -58,47 +64,47 @@ contract CasimirManager is ICasimirManager, CasimirCore, Initializable, OwnableU
uint256 public reservedFeeBalance;
/// @inheritdoc ICasimirManager
uint256 public requestedExits;
/**
/**
* @dev Chainlink functions billing registry contract
* @custom:oz-upgrades-unsafe-allow state-variable-immutable
*/
IFunctionsBillingRegistry private immutable functionsBillingRegistry;
/**
/**
* @dev LINK ERC-20 token contract
* @custom:oz-upgrades-unsafe-allow state-variable-immutable
*/
LinkTokenInterface private immutable linkToken;
/**
/**
* @dev Keeper registrar contract
* @custom:oz-upgrades-unsafe-allow state-variable-immutable
*/
IKeeperRegistrar private immutable keeperRegistrar;
/**
/**
* @dev Automation registry contract
* @custom:oz-upgrades-unsafe-allow state-variable-immutable
*/
IAutomationRegistry private immutable keeperRegistry;
/**
/**
* @dev SSV clusters contract
* @custom:oz-upgrades-unsafe-allow state-variable-immutable
*/
ISSVClusters private immutable ssvClusters;
/**
/**
* @dev SSV ERC-20 token contract
* @custom:oz-upgrades-unsafe-allow state-variable-immutable
*/
IERC20Upgradeable private immutable ssvToken;
/**
/**
* @dev Uniswap factory contract
* @custom:oz-upgrades-unsafe-allow state-variable-immutable
*/
IUniswapV3Factory private immutable swapFactory;
/**
/**
* @dev Uniswap router contract
* @custom:oz-upgrades-unsafe-allow state-variable-immutable
*/
ISwapRouter private immutable swapRouter;
/**
/**
* @dev WETH9 ERC-20 token contract
* @custom:oz-upgrades-unsafe-allow state-variable-immutable
*/
Expand Down Expand Up @@ -385,31 +391,33 @@ contract CasimirManager is ICasimirManager, CasimirCore, Initializable, OwnableU
int256 rewards = int256(beaconBalance + sweptBalance + finalizableRecoveredBalance) -
int256(expectedEffectiveBalance + expectedExitedBalance);
int256 change = rewards - latestActiveRewardBalance;
if (change > 0) {
uint256 gain = uint256(change);
if (rewards > 0) {
uint256 gainAfterFees = subtractFees(gain);
stakeRatioSum += MathUpgradeable.mulDiv(stakeRatioSum, gainAfterFees, getTotalStake());
latestBeaconBalanceAfterFees += gainAfterFees;
emit StakeRebalanced(gainAfterFees);
} else {
stakeRatioSum += MathUpgradeable.mulDiv(stakeRatioSum, gain, getTotalStake());
latestBeaconBalanceAfterFees += gain;
emit StakeRebalanced(gain);
if (latestBeaconBalanceAfterFees > 0) {
if (change > 0) {
uint256 gain = uint256(change);
if (rewards > 0) {
uint256 gainAfterFees = subtractFees(gain);
stakeRatioSum += MathUpgradeable.mulDiv(stakeRatioSum, gainAfterFees, getTotalStake());
latestBeaconBalanceAfterFees += gainAfterFees;
emit StakeRebalanced(gainAfterFees);
} else {
stakeRatioSum += MathUpgradeable.mulDiv(stakeRatioSum, gain, getTotalStake());
latestBeaconBalanceAfterFees += gain;
emit StakeRebalanced(gain);
}
} else if (change < 0) {
uint256 loss = uint256(-change);
stakeRatioSum -= MathUpgradeable.mulDiv(stakeRatioSum, loss, getTotalStake());
latestBeaconBalanceAfterFees -= loss;
emit StakeRebalanced(loss);
}
} else if (change < 0) {
uint256 loss = uint256(-change);
stakeRatioSum -= MathUpgradeable.mulDiv(stakeRatioSum, loss, getTotalStake());
latestBeaconBalanceAfterFees -= loss;
emit StakeRebalanced(loss);
}
int256 sweptRewards = int256(sweptBalance + finalizableRecoveredBalance) - int256(finalizableExitedBalance);
if (sweptRewards > 0) {
latestBeaconBalanceAfterFees -= subtractFees(uint256(sweptRewards));
int256 sweptRewards = int256(sweptBalance + finalizableRecoveredBalance) - int256(finalizableExitedBalance);
if (sweptRewards > 0) {
latestBeaconBalanceAfterFees -= subtractFees(uint256(sweptRewards));
}
latestBeaconBalanceAfterFees -= finalizableExitedBalance;
latestActiveRewardBalance = rewards - sweptRewards;
}
latestBeaconBalanceAfterFees -= finalizableExitedBalance;
latestBeaconBalanceAfterFees += expectedActivatedBalance;
latestActiveRewardBalance = rewards - sweptRewards;
latestBeaconBalance = beaconBalance;
finalizableExitedBalance = 0;
finalizableRecoveredBalance = 0;
Expand Down Expand Up @@ -734,12 +742,12 @@ contract CasimirManager is ICasimirManager, CasimirCore, Initializable, OwnableU

/// @inheritdoc ICasimirManager
function getTotalStake() public view returns (uint256 totalStake) {
totalStake = getBufferedBalance() + latestBeaconBalanceAfterFees - requestedWithdrawalBalance;
}

/// @inheritdoc ICasimirManager
function getBufferedBalance() public view returns (uint256 bufferedBalance) {
bufferedBalance = getWithdrawableBalance() + readyPoolIds.length * POOL_CAPACITY;
totalStake =
getWithdrawableBalance() +
(readyPoolIds.length + pendingPoolIds.length) *
POOL_CAPACITY +
latestBeaconBalanceAfterFees -
requestedWithdrawalBalance;
}

/// @inheritdoc ICasimirManager
Expand Down
Loading

0 comments on commit 3b79d03

Please sign in to comment.