From 337ebdb41fdcb3236bfd1761ed261a8b2c899b08 Mon Sep 17 00:00:00 2001 From: Alex Rea Date: Fri, 11 Aug 2023 15:25:34 +0100 Subject: [PATCH] Fix setExpenditurePayouts logic --- contracts/colony/ColonyFunding.sol | 9 ++-- test/contracts-network/colony-expenditure.js | 45 ++++++++++++++++++++ 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/contracts/colony/ColonyFunding.sol b/contracts/colony/ColonyFunding.sol index 8d8ec45a07..ce6b4641ae 100755 --- a/contracts/colony/ColonyFunding.sol +++ b/contracts/colony/ColonyFunding.sol @@ -409,7 +409,8 @@ contract ColonyFunding is ColonyStorage { // ignore-swc-123 FundingPot storage fundingPot = fundingPots[expenditures[_id].fundingPotId]; assert(fundingPot.associatedType == FundingPotAssociatedType.Expenditure); - uint256 currentTotal = fundingPot.payouts[_token]; + uint256 previousTotal = fundingPot.payouts[_token]; + uint256 runningTotal = fundingPot.payouts[_token]; for (uint256 i; i < _slots.length; i++) { require(_amounts[i] <= MAX_PAYOUT, "colony-payout-too-large"); @@ -417,13 +418,13 @@ contract ColonyFunding is ColonyStorage { // ignore-swc-123 uint256 currentPayout = expenditureSlotPayouts[_id][_slots[i]][_token]; expenditureSlotPayouts[_id][_slots[i]][_token] = _amounts[i]; - fundingPot.payouts[_token] = (currentTotal - currentPayout) + _amounts[i]; - + runningTotal = (runningTotal - currentPayout) + _amounts[i]; emit ExpenditurePayoutSet(msgSender(), _id, _slots[i], _token, _amounts[i]); } + fundingPot.payouts[_token] = runningTotal; - updatePayoutsWeCannotMakeAfterBudgetChange(expenditures[_id].fundingPotId, _token, currentTotal); + updatePayoutsWeCannotMakeAfterBudgetChange(expenditures[_id].fundingPotId, _token, previousTotal); } function setTaskPayout(uint256 _id, TaskRole _role, address _token, uint256 _amount) private diff --git a/test/contracts-network/colony-expenditure.js b/test/contracts-network/colony-expenditure.js index 9cfe2de1b8..9d76f2724d 100644 --- a/test/contracts-network/colony-expenditure.js +++ b/test/contracts-network/colony-expenditure.js @@ -367,6 +367,11 @@ contract("Colony Expenditure", (accounts) => { expect(payout).to.eq.BN(10); payout = await colony.getExpenditureSlotPayout(expenditureId, SLOT2, token.address); expect(payout).to.eq.BN(20); + + const expenditure = await colony.getExpenditure(expenditureId); + const fundingPotId = await expenditure.fundingPotId; + const fundingPotPayout = await colony.getFundingPotPayout(fundingPotId, token.address); + expect(fundingPotPayout).to.eq.BN(30); }); it("should not allow owners to update many slot payouts with mismatched arguments", async () => { @@ -939,6 +944,46 @@ contract("Colony Expenditure", (accounts) => { expect(potPayout).to.be.zero; }); + it("should be able to pay out all recipients if setExpenditurePayouts is used to set recipients", async () => { + await colony.setExpenditureRecipient(expenditureId, SLOT0, RECIPIENT, { from: ADMIN }); + await colony.setExpenditureRecipient(expenditureId, SLOT1, RECIPIENT, { from: ADMIN }); + + await colony.setExpenditurePayouts(expenditureId, [SLOT0, SLOT1], token.address, [10, 20], { from: ADMIN }); + + let expenditure = await colony.getExpenditure(expenditureId); + + await colony.moveFundsBetweenPots( + 1, + UINT256_MAX, + 1, + UINT256_MAX, + UINT256_MAX, + domain1.fundingPotId, + expenditure.fundingPotId, + 30, + token.address + ); + await colony.finalizeExpenditure(expenditureId, { from: ADMIN }); + + expenditure = await colony.getExpenditure(expenditureId); + + const balanceBefore = await colony.getFundingPotBalance(expenditure.fundingPotId, token.address); + await colony.claimExpenditurePayout(expenditureId, SLOT0, token.address); + const balanceAfter = await colony.getFundingPotBalance(expenditure.fundingPotId, token.address); + expect(balanceBefore.sub(balanceAfter)).to.eq.BN(10); + + let potBalance = await colony.getFundingPotBalance(expenditure.fundingPotId, token.address); + let potPayout = await colony.getFundingPotPayout(expenditure.fundingPotId, token.address); + expect(potBalance).to.eq.BN(20); + expect(potPayout).to.eq.BN(20); + + await colony.claimExpenditurePayout(expenditureId, SLOT1, token.address); + potBalance = await colony.getFundingPotBalance(expenditure.fundingPotId, token.address); + potPayout = await colony.getFundingPotPayout(expenditure.fundingPotId, token.address); + expect(potBalance).to.be.zero; + expect(potPayout).to.be.zero; + }); + it("if skill is set, should emit two reputation updates", async () => { await colony.setExpenditureRecipient(expenditureId, SLOT0, RECIPIENT, { from: ADMIN }); await colony.setExpenditurePayout(expenditureId, SLOT0, token.address, WAD, { from: ADMIN });