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

When health changes update #208

Merged
merged 16 commits into from
Nov 6, 2024
12 changes: 9 additions & 3 deletions contracts/Account.sol
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,12 @@ contract Account is UUPSOwnableUpgradeable, UsingRegistryUpgradeable, Managed, I
* @notice Scheduling transfer was not successfull since
* total amount of "from" and "to" are not the same.
*/
error TransferAmountMisalignment();
error TransferAmountMisalignment(uint256 totalFromVotes, uint256 totalToVotes);

/**
* @notice When scheduling transfer and the from group doesn't have enough CELO.
*/
error NotEnoughCeloInGroup(address group, uint256 expectedAmount, uint256 realAmount);

/**
* @notice Empty constructor for proxy implementation, `initializer` modifer ensures the
Expand Down Expand Up @@ -288,7 +293,8 @@ contract Account is UUPSOwnableUpgradeable, UsingRegistryUpgradeable, Managed, I
for (uint256 i = 0; i < fromGroups.length; i++) {
uint256 celoAvailableForGroup = getCeloForGroup(fromGroups[i]);

if (celoAvailableForGroup < fromVotes[i]) revert TransferAmountMisalignment();
if (celoAvailableForGroup < fromVotes[i])
revert NotEnoughCeloInGroup(fromGroups[i], fromVotes[i], celoAvailableForGroup);
getAndUpdateToVoteAndToRevoke(fromGroups[i], 0, fromVotes[i]);
totalFromVotes += fromVotes[i];
}
Expand All @@ -299,7 +305,7 @@ contract Account is UUPSOwnableUpgradeable, UsingRegistryUpgradeable, Managed, I
}

if (totalFromVotes != totalToVotes) {
revert TransferAmountMisalignment();
revert TransferAmountMisalignment(totalFromVotes, totalToVotes);
}
}

Expand Down
31 changes: 20 additions & 11 deletions contracts/DefaultStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -291,12 +291,16 @@ contract DefaultStrategy is Errors, UUPSOwnableUpgradeable, Managed, Pausable {
* @return finalGroups The groups that were chosen for distribution.
* @return finalVotes The votes of chosen finalGroups.
*/
function generateDepositVoteDistribution(uint256 celoAmount, address depositGroupToIgnore)
function generateDepositVoteDistribution(
uint256 celoAmount,
uint256 stCeloAmount,
address depositGroupToIgnore
)
external
managerOrStrategy
returns (address[] memory finalGroups, uint256[] memory finalVotes)
{
return _generateDepositVoteDistribution(celoAmount, depositGroupToIgnore);
return _generateDepositVoteDistribution(celoAmount, stCeloAmount, depositGroupToIgnore);
}

/**
Expand Down Expand Up @@ -694,6 +698,7 @@ contract DefaultStrategy is Errors, UUPSOwnableUpgradeable, Managed, Pausable {
_updateGroupStCelo(group, groupTotalStCeloVotes, false);
_generateDepositVoteDistribution(
IManager(manager).toCelo(groupTotalStCeloVotes),
groupTotalStCeloVotes,
address(0)
);
}
Expand All @@ -709,10 +714,11 @@ contract DefaultStrategy is Errors, UUPSOwnableUpgradeable, Managed, Pausable {
* @return finalGroups The groups that were chosen for distribution.
* @return finalVotes The votes of chosen finalGroups.
*/
function _generateDepositVoteDistribution(uint256 celoAmount, address depositGroupToIgnore)
private
returns (address[] memory finalGroups, uint256[] memory finalVotes)
{
function _generateDepositVoteDistribution(
uint256 celoAmount,
uint256 stCeloAmount,
address depositGroupToIgnore
) private returns (address[] memory finalGroups, uint256[] memory finalVotes) {
if (activeGroups.getNumElements() == 0) {
revert NoActiveGroups();
}
Expand All @@ -735,11 +741,9 @@ contract DefaultStrategy is Errors, UUPSOwnableUpgradeable, Managed, Pausable {
votes[groupsIndex] = Math.min(receivableVotes, celoAmount);
groups[groupsIndex] = votedGroup;
celoAmount -= votes[groupsIndex];
_updateGroupStCelo(
votedGroup,
IManager(manager).toStakedCelo(votes[groupsIndex]),
true
);
uint256 stCelo = IManager(manager).toStakedCelo(votes[groupsIndex]);
stCeloAmount = stCeloAmount >= stCelo ? stCeloAmount - stCelo : 0;
_updateGroupStCelo(votedGroup, stCelo, true);
trySort(votedGroup, stCeloInGroup[votedGroup], true);

if (sorted) {
Expand All @@ -754,6 +758,11 @@ contract DefaultStrategy is Errors, UUPSOwnableUpgradeable, Managed, Pausable {
revert NotAbleToDistributeVotes();
}

if (stCeloAmount != 0) {
_updateGroupStCelo(votedGroup, stCeloAmount, true);
trySort(votedGroup, stCeloInGroup[votedGroup], true);
}

finalGroups = new address[](groupsIndex);
finalVotes = new uint256[](groupsIndex);

Expand Down
3 changes: 3 additions & 0 deletions contracts/Manager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,8 @@ contract Manager is Errors, UUPSOwnableUpgradeable, UsingRegistryUpgradeable, Pa
return (celoToRemove - celoScheduled, 0);
}

// TODO: check if we could rebalance to unhealthy group if needed
pahor167 marked this conversation as resolved.
Show resolved Hide resolved

actualCelo = celoScheduled - celoToRemove;

bool isSpecificGroupStrategy = !specificGroupStrategy.isBlockedGroup(group);
Expand Down Expand Up @@ -635,6 +637,7 @@ contract Manager is Errors, UUPSOwnableUpgradeable, UsingRegistryUpgradeable, Pa
} else {
(finalGroups, finalVotes) = defaultStrategy.generateDepositVoteDistribution(
votes,
stCeloAmount,
address(0)
);
}
Expand Down
26 changes: 15 additions & 11 deletions contracts/SpecificGroupStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -333,14 +333,14 @@ contract SpecificGroupStrategy is Errors, UUPSOwnableUpgradeable, Managed, Pausa

celoAmount -= votesToBeScheduledForSpecificGroup;
if (celoAmount > 0) {
uint256 stCeloAmountOverflow = Math.min(
IManager(manager).toStakedCelo(celoAmount),
stCeloAmount
);
// overflow
(address[] memory groups, uint256[] memory votesForGroups) = defaultStrategy
.generateDepositVoteDistribution(celoAmount, group);
updateOverflowGroup(
group,
Math.min(IManager(manager).toStakedCelo(celoAmount), stCeloAmount),
true
);
.generateDepositVoteDistribution(celoAmount, stCeloAmountOverflow, group);
updateOverflowGroup(group, stCeloAmountOverflow, true);
finalGroups = new address[](groups.length + 1);
finalVotes = new uint256[](groups.length + 1);
for (uint256 i = 0; i < groups.length; i++) {
Expand All @@ -358,6 +358,7 @@ contract SpecificGroupStrategy is Errors, UUPSOwnableUpgradeable, Managed, Pausa
} else {
(finalGroups, finalVotes) = defaultStrategy.generateDepositVoteDistribution(
celoAmount,
stCeloAmount,
group
);
updateUnhealthyGroupStCelo(group, stCeloAmount, true);
Expand Down Expand Up @@ -391,10 +392,10 @@ contract SpecificGroupStrategy is Errors, UUPSOwnableUpgradeable, Managed, Pausa
}

uint256 overflow = stCeloInGroupOverflowed[group];
uint256 toMove = totalStCeloInGroup - unhealthyStCelo - overflow;
uint256 toMoveStCelo = totalStCeloInGroup - unhealthyStCelo - overflow;

transferToDefaultStrategy(group, toMove);
updateUnhealthyGroupStCelo(group, toMove, true);
transferToDefaultStrategy(group, toMoveStCelo);
updateUnhealthyGroupStCelo(group, toMoveStCelo, true);
}
}

Expand Down Expand Up @@ -602,13 +603,16 @@ contract SpecificGroupStrategy is Errors, UUPSOwnableUpgradeable, Managed, Pausa
* @param stCeloToMove StCelo amount to be moved.
*/
function transferToDefaultStrategy(address group, uint256 stCeloToMove) private {
uint256 toMoveCelo = IManager(manager).toCelo(stCeloToMove);
uint256 toMoveCelo = Math.min(
account.getCeloForGroup(group),
IManager(manager).toCelo(stCeloToMove)
);
address[] memory fromGroups = new address[](1);
uint256[] memory fromVotes = new uint256[](1);
fromGroups[0] = group;
fromVotes[0] = toMoveCelo;
(address[] memory toGroups, uint256[] memory toVotes) = defaultStrategy
.generateDepositVoteDistribution(toMoveCelo, address(0));
.generateDepositVoteDistribution(toMoveCelo, stCeloToMove, address(0));
IManager(manager).scheduleTransferWithinStrategy(fromGroups, toGroups, fromVotes, toVotes);
}

Expand Down
8 changes: 5 additions & 3 deletions contracts/interfaces/IDefaultStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
pragma solidity 0.8.11;

interface IDefaultStrategy {
function generateDepositVoteDistribution(uint256 celoAmount, address depositGroupToIgnore)
external
returns (address[] memory finalGroups, uint256[] memory finalVotes);
function generateDepositVoteDistribution(
uint256 celoAmount,
uint256 stCeloAmount,
address depositGroupToIgnore
) external returns (address[] memory finalGroups, uint256[] memory finalVotes);

function generateWithdrawalVoteDistribution(uint256 celoAmount)
external
Expand Down
6 changes: 3 additions & 3 deletions test-ts/account.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -520,15 +520,15 @@ describe("Account", () => {
account
.connect(manager)
.scheduleTransfer(groupAddresses, [100, 30, 80], groupAddresses, [30, 70, 100])
).revertedWith(`TransferAmountMisalignment()`);
).revertedWith(`'NotEnoughCeloInGroup("${groupAddresses[0]}", 100, 0)`);
});

it("should revert when incorrect vote sum 2", async () => {
await expect(
account
.connect(manager)
.scheduleTransfer(groupAddresses, [100, 30, 60], groupAddresses, [30, 70, 100])
).revertedWith(`TransferAmountMisalignment()`);
).revertedWith(`NotEnoughCeloInGroup("${groupAddresses[0]}", 100, 0)`);
});

describe("When group has activated votes", () => {
Expand Down Expand Up @@ -645,7 +645,7 @@ describe("Account", () => {
[groupAddresses[1]],
[originalGroupAmount * 2]
)
).revertedWith(`TransferAmountMisalignment()`);
).revertedWith(`NotEnoughCeloInGroup("${groupAddresses[0]}", 200, 100)`);
});
});

Expand Down
2 changes: 1 addition & 1 deletion test-ts/default-strategy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1250,7 +1250,7 @@ describe("DefaultStrategy", () => {
await expect(
defaultStrategyContract
.connect(nonManager)
.generateDepositVoteDistribution(10, ADDRESS_ZERO)
.generateDepositVoteDistribution(10, 10, ADDRESS_ZERO)
).revertedWith(`CallerNotManagerNorStrategy("${nonManager.address}")`);
});
});
Expand Down
Loading
Loading