Skip to content

Commit

Permalink
🐛 fix stakedAmount updates
Browse files Browse the repository at this point in the history
🐛 fix threshold formula
✨ created better constants for testing
🧪 2 new tests, totalStaked and threshold
  • Loading branch information
kamikazebr committed Dec 27, 2023
1 parent 2811fad commit 9bba721
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 21 deletions.
21 changes: 16 additions & 5 deletions pkg/contracts/src/CVStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -442,8 +442,15 @@ contract CVStrategy is BaseStrategy, IWithdrawMember {
uint256 stakedAmount = convertPctToTokens(stakedPointsPct);
console.log("stakedAmount", stakedAmount);
proposal.voterStake[_sender] = stakedAmount;
proposal.stakedAmount += proposal.voterStake[_sender];

// proposal.stakedAmount += stakedAmount;
// uint256 diff =_diffStakedTokens(previousStakedAmount, stakedAmount);
if (previousStakedAmount <= stakedAmount) {
totalStaked += stakedAmount - previousStakedAmount;
proposal.stakedAmount += stakedAmount - previousStakedAmount;
} else {
totalStaked -= previousStakedAmount - stakedAmount;
proposal.stakedAmount -= previousStakedAmount - stakedAmount;
}
//@todo: should emit event
if (proposal.blockLast == 0) {
proposal.blockLast = block.number;
Expand Down Expand Up @@ -512,7 +519,7 @@ contract CVStrategy is BaseStrategy, IWithdrawMember {
uint256 funds = poolAmount;
// require(maxRatio.mul(funds) > _requestedAmount.mul(D), ERROR_AMOUNT_OVER_MAX_RATIO);
// console.log("maxRatio", maxRatio);
// console.log("funds", funds);
// console.log("funds/poolAmount", funds);
// console.log("_requestedAmount", _requestedAmount);
// console.log("D", D);
// console.log("maxRatio * funds", maxRatio * funds);
Expand All @@ -530,7 +537,10 @@ contract CVStrategy is BaseStrategy, IWithdrawMember {
// _threshold =
// ((weight << 128).div(D).div(denom.mul(denom) >> 64)).mul(D).div(D.sub(decay)).mul(_totalStaked()) >> 64;
// _threshold = (((weight << 128) / D) / (denom.mul(denom) >> 64)) * D / (D - decay) * (_totalStaked()) >> 64;
_threshold = ((weight * 2 ** 128 / D / (denom * denom >> 64)) * D / (D - decay) * _totalStaked()) >> 64;
// _threshold = ((weight * 2 ** 128 / D / (denom * denom >> 64)) * D / (D - decay) * _totalStaked()) >> 64;

// _threshold = ( (weight << 128).div(D).div(denom.mul(denom) >> 64)).mul(D).div(D.sub(decay)).mul(_totalStaked()) >> 64;
_threshold = ((((((weight << 128) / D) / ((denom * denom) >> 64)) * D) / (D - decay)) * _totalStaked()) >> 64;
// console.log("_threshold", _threshold);
}

Expand Down Expand Up @@ -596,11 +606,12 @@ contract CVStrategy is BaseStrategy, IWithdrawMember {
if (address(registryGardens.gardenToken()) == address(0)) {
revert TokenCannotBeZero();
}
// console.log("totalStaked", totalStaked);
// console.log("registryGardens.gardenToken.totalSupply()", registryGardens.gardenToken().totalSupply());
// console.log("minThresholdStakePercentage", minThresholdStakePercentage);
uint256 minTotalStake =
(registryGardens.gardenToken().totalSupply() * minThresholdStakePercentage) / ONE_HUNDRED_PERCENT;
// console.log("minTotalStake", minTotalStake);
// console.log("totalStaked", totalStaked);
return totalStaked < minTotalStake ? minTotalStake : totalStaked;
}
}
2 changes: 1 addition & 1 deletion pkg/contracts/src/RegistryGardens.sol
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ contract RegistryGardens is ReentrancyGuard {

//@todo: maybe we want use ROLES instead fixed address that give mroe flexibility
//@todo: also who should be allowed to set the council members? the DAO? the garden owner?
function setCouncilMembers(address[] memory _members) public onlyGardenOwner{
function setCouncilMembers(address[] memory _members) public onlyGardenOwner {
for (uint256 i = 0; i < _members.length; i++) {
councilMembers[_members[i]] = true;
}
Expand Down
123 changes: 108 additions & 15 deletions pkg/contracts/test/CVStrategyTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ import {RegistryFactory} from "../src/RegistryFactory.sol";
contract CVStrategyTest is Test, AlloSetup, RegistrySetupFull, Native, Errors, GasHelpers {
CVStrategy public strategy;
MockERC20 public token;
uint256 public mintAmount = 1_000_000 * 10 ** 18;
// uint256 public mintAmount = 1_000 * 10 ** 18;
uint256 public mintAmount = 15000;
uint256 public constant TOTAL_SUPPLY = 45000;
uint256 public constant POOL_AMOUNT = 15000;
uint256 public constant MINIMUM_STAKE = 50;
uint256 public constant REQUESTED_AMOUNT = 1000;

Metadata public metadata = Metadata({protocol: 1, pointer: "strategy pointer"});

Expand All @@ -54,12 +58,7 @@ contract CVStrategyTest is Test, AlloSetup, RegistrySetupFull, Native, Errors, G
vm.stopPrank();

token = new MockERC20();
token.mint(local(), mintAmount);
token.mint(allo_owner(), mintAmount);
token.mint(pool_admin(), mintAmount);
token.approve(address(allo()), mintAmount);

vm.prank(pool_admin());
token.mint(local(), TOTAL_SUPPLY);
token.approve(address(allo()), mintAmount);

strategy = new CVStrategy(address(allo()));
Expand All @@ -77,6 +76,12 @@ contract CVStrategyTest is Test, AlloSetup, RegistrySetupFull, Native, Errors, G
params._protocolFee = 2;
params._metadata = metadata;
registryGardens = RegistryGardens(registryFactory.createRegistry(params));

address[] memory initialmembers = new address[](2);
initialmembers[0] = local();
initialmembers[1] = pool_admin();

registryGardens.setCouncilMembers(initialmembers);
}

function _registryGardens() internal view returns (RegistryGardens) {
Expand All @@ -92,8 +97,6 @@ contract CVStrategyTest is Test, AlloSetup, RegistrySetupFull, Native, Errors, G
Metadata metadata
);

// bytes data;

/**
* HELPERS FUNCTIONS
*/
Expand Down Expand Up @@ -122,14 +125,14 @@ contract CVStrategyTest is Test, AlloSetup, RegistrySetupFull, Native, Errors, G
pool = allo().getPool(poolId);

vm.deal(address(this), 1 ether);
allo().fundPool{value: 1 ether}(poolId, 1 ether);
allo().fundPool{value: POOL_AMOUNT}(poolId, POOL_AMOUNT);

assertEq(pool.profileId, poolProfile_id());
assertNotEq(address(pool.strategy), address(strategy));

startMeasuringGas("createProposal");
CVStrategy.CreateProposal memory proposal = CVStrategy.CreateProposal(
1, poolId, pool_admin(), pool_admin(), CVStrategy.ProposalType.Signaling, 0.1 ether, NATIVE
1, poolId, pool_admin(), pool_admin(), CVStrategy.ProposalType.Signaling, REQUESTED_AMOUNT, NATIVE
);
bytes memory data = abi.encode(proposal);
allo().registerRecipient(poolId, data);
Expand Down Expand Up @@ -230,23 +233,23 @@ contract CVStrategyTest is Test, AlloSetup, RegistrySetupFull, Native, Errors, G
assertEq(cv.getProposalStakedAmount(1), 40 + 50);
}

function test_proposalSupported_conviction_check() public {
function test_conviction_check_function() public {
(IAllo.Pool memory pool, uint256 poolId) = _createProposal();

/**
* ASSERTS
*/
startMeasuringGas("Support a Proposal");
CVStrategy.ProposalSupport[] memory votes = new CVStrategy.ProposalSupport[](1);
votes[0] = CVStrategy.ProposalSupport(1, 80); // 0 + 70 = 70% = 35
votes[0] = CVStrategy.ProposalSupport(1, 80);
bytes memory data = abi.encode(votes);
allo().allocate(poolId, data);
stopMeasuringGas();

uint256 AMOUNT_STAKED = 40;
CVStrategy cv = CVStrategy(payable(address(pool.strategy)));
assertEq(cv.getProposalVoterStake(1, address(this)), AMOUNT_STAKED); // 80% of 50 = 40
assertEq(cv.getProposalStakedAmount(1), AMOUNT_STAKED); // 80% of 50 = 40
assertEq(cv.getProposalVoterStake(1, address(this)), AMOUNT_STAKED);
assertEq(cv.getProposalStakedAmount(1), AMOUNT_STAKED);

uint256 cv_amount = cv.calculateConviction(10, 0, AMOUNT_STAKED);
console.log("cv_amount: %s", cv_amount);
Expand All @@ -255,6 +258,96 @@ contract CVStrategyTest is Test, AlloSetup, RegistrySetupFull, Native, Errors, G
assertEq(cv_amount, cv_cmp);
}

function test_conviction_check_as_js_test() public {
(IAllo.Pool memory pool, uint256 poolId) = _createProposal();
uint256 AMOUNT_STAKED = 45000;

registryGardens.setBasisStakedAmount(AMOUNT_STAKED);
/**
* ASSERTS
*/
startMeasuringGas("Support a Proposal");
CVStrategy.ProposalSupport[] memory votes = new CVStrategy.ProposalSupport[](1);
votes[0] = CVStrategy.ProposalSupport(1, 100);
bytes memory data = abi.encode(votes);
allo().allocate(poolId, data);
stopMeasuringGas();

CVStrategy cv = CVStrategy(payable(address(pool.strategy)));
assertEq(cv.getProposalVoterStake(1, address(this)), AMOUNT_STAKED);
assertEq(cv.getProposalStakedAmount(1), AMOUNT_STAKED);

uint256 AMOUNT_STAKED_1 = 15000;
uint256 cv_amount = cv.calculateConviction(10, 0, AMOUNT_STAKED_1);

console.log("cv_amount: %s", cv_amount);
uint256 cv_cmp = _calculateConviction(10, 0, AMOUNT_STAKED_1, 0.9 ether / 10 ** 11);
console.log("cv_cmp: %s", cv_cmp);

assertEq(cv_amount, cv_cmp);
assertEq(AMOUNT_STAKED_1, 15000);
assertEq(AMOUNT_STAKED, 45000);
assertEq(cv_amount, 97698);

registryGardens.setBasisStakedAmount(MINIMUM_STAKE);
}

function test_threshold_check_as_js_test() public {
(IAllo.Pool memory pool, uint256 poolId) = _createProposal();
registryGardens.setBasisStakedAmount(45000);
/**
* ASSERTS
*/
startMeasuringGas("Support a Proposal");
CVStrategy.ProposalSupport[] memory votes = new CVStrategy.ProposalSupport[](1);
votes[0] = CVStrategy.ProposalSupport(1, 100); // 0 + 70 = 70% = 35
bytes memory data = abi.encode(votes);
allo().allocate(poolId, data);
stopMeasuringGas();

uint256 AMOUNT_STAKED = 45000;
CVStrategy cv = CVStrategy(payable(address(pool.strategy)));
assertEq(cv.getProposalVoterStake(1, address(this)), AMOUNT_STAKED); // 80% of 50 = 40
assertEq(cv.getProposalStakedAmount(1), AMOUNT_STAKED); // 80% of 50 = 40

uint256 ct1 = cv.calculateThreshold(REQUESTED_AMOUNT);

assertEq(AMOUNT_STAKED, 45000);
assertEq(ct1, 50625);

registryGardens.setBasisStakedAmount(MINIMUM_STAKE);
}

function test_total_staked_amount() public {
(IAllo.Pool memory pool, uint256 poolId) = _createProposal();
registryGardens.setBasisStakedAmount(45000);
/**
* ASSERTS
*/
// startMeasuringGas("Support a Proposal");
CVStrategy.ProposalSupport[] memory votes = new CVStrategy.ProposalSupport[](1);
votes[0] = CVStrategy.ProposalSupport(1, 100);
bytes memory data = abi.encode(votes);
allo().allocate(poolId, data);
// stopMeasuringGas();

uint256 AMOUNT_STAKED = 45000;
CVStrategy cv = CVStrategy(payable(address(pool.strategy)));
assertEq(cv.getProposalVoterStake(1, address(this)), AMOUNT_STAKED);
assertEq(cv.getProposalStakedAmount(1), AMOUNT_STAKED);

votes[0] = CVStrategy.ProposalSupport(1, -100);
data = abi.encode(votes);
allo().allocate(poolId, data);

assertEq(cv.getProposalVoterStake(1, address(this)), 0, "VoterStake");
assertEq(cv.getProposalStakedAmount(1), 0, "StakedAmount");

assertEq(cv.totalStaked(), 0, "TotalStaked");

registryGardens.setBasisStakedAmount(MINIMUM_STAKE);
}

function testRevert_allocate_removeSupport_wo_support_before_SUPPORT_UNDERFLOW() public {
(IAllo.Pool memory pool, uint256 poolId) = _createProposal();

Expand Down

0 comments on commit 9bba721

Please sign in to comment.