diff --git a/contracts/accessory/gift-cards/GiftCards.sol b/contracts/accessory/gift-cards/GiftCards.sol index ef86679a7..7b6b31ae0 100644 --- a/contracts/accessory/gift-cards/GiftCards.sol +++ b/contracts/accessory/gift-cards/GiftCards.sol @@ -186,7 +186,8 @@ contract GiftCards is Storage, Initializable, OwnableUpgradeable, ReentrancyGuar AccountMessages.DepositRequest({ id: endowmentId, lockedPercentage: lockedPercentage, - liquidPercentage: liquidPercentage + liquidPercentage: liquidPercentage, + donationMatch: msg.sender }), tokenAddress, amount diff --git a/contracts/core/accounts/facets/AccountsDepositWithdrawEndowments.sol b/contracts/core/accounts/facets/AccountsDepositWithdrawEndowments.sol index a298e3315..81ba3ad79 100644 --- a/contracts/core/accounts/facets/AccountsDepositWithdrawEndowments.sol +++ b/contracts/core/accounts/facets/AccountsDepositWithdrawEndowments.sol @@ -115,7 +115,6 @@ contract AccountsDepositWithdrawEndowments is uint256 liquidSplitPercent = details.liquidPercentage; require(registrar_config.indexFundContract != address(0), "No Index Fund"); - if (msg.sender != registrar_config.indexFundContract) { if (tempEndowment.endowType == LibAccounts.EndowmentType.Charity) { // use the Registrar default split for Charities @@ -139,9 +138,13 @@ contract AccountsDepositWithdrawEndowments is uint256 lockedAmount = (amount.mul(lockedSplitPercent)).div(LibAccounts.PERCENT_BASIS); uint256 liquidAmount = (amount.mul(liquidSplitPercent)).div(LibAccounts.PERCENT_BASIS); - //donation matching flow - //execute donor match will always be called on an EOA + // donation matching flow if (lockedAmount > 0) { + address donationMatch = details.donationMatch; + if (donationMatch == address(0)) { + donationMatch = msg.sender; + } + if ( tempEndowment.endowType == LibAccounts.EndowmentType.Charity && registrar_config.donationMatchCharitesContract != address(0) @@ -149,17 +152,14 @@ contract AccountsDepositWithdrawEndowments is IDonationMatching(registrar_config.donationMatchCharitesContract).executeDonorMatch( details.id, lockedAmount, - tx.origin, + donationMatch, registrar_config.haloToken ); - } else if ( - tempEndowment.endowType == LibAccounts.EndowmentType.Normal && - tempEndowment.donationMatchContract != address(0) - ) { + } else if (tempEndowment.donationMatchContract != address(0)) { IDonationMatching(tempEndowment.donationMatchContract).executeDonorMatch( details.id, lockedAmount, - tx.origin, + donationMatch, tempEndowment.daoToken ); } @@ -330,7 +330,8 @@ contract AccountsDepositWithdrawEndowments is AccountMessages.DepositRequest({ id: beneficiaryEndowId, lockedPercentage: 0, - liquidPercentage: 100 + liquidPercentage: 100, + donationMatch: address(this) // all liquid so won't trigger a match }), tokens[t].addr, (amountLeftover - withdrawFeeEndow) diff --git a/contracts/core/accounts/message.sol b/contracts/core/accounts/message.sol index 18538cc12..0d8fa8aaf 100644 --- a/contracts/core/accounts/message.sol +++ b/contracts/core/accounts/message.sol @@ -121,6 +121,7 @@ library AccountMessages { uint32 id; uint256 lockedPercentage; uint256 liquidPercentage; + address donationMatch; } struct InvestRequest { diff --git a/contracts/core/index-fund/IndexFund.sol b/contracts/core/index-fund/IndexFund.sol index c3830913b..77aa4a8b4 100644 --- a/contracts/core/index-fund/IndexFund.sol +++ b/contracts/core/index-fund/IndexFund.sol @@ -508,7 +508,8 @@ contract IndexFund is IIndexFund, Storage, ReentrancyGuard, Initializable { AccountMessages.DepositRequest({ id: donationMessages.member_ids[i], lockedPercentage: donationMessages.lockedSplit[i], - liquidPercentage: donationMessages.liquidSplit[i] + liquidPercentage: donationMessages.liquidSplit[i], + donationMatch: msg.sender }), tokenaddress, donationMessages.locked_donation_amount[i] + donationMessages.liquid_donation_amount[i] diff --git a/contracts/multisigs/CharityApplications.sol b/contracts/multisigs/CharityApplications.sol index 3655eebc3..f4055b38f 100644 --- a/contracts/multisigs/CharityApplications.sol +++ b/contracts/multisigs/CharityApplications.sol @@ -239,7 +239,8 @@ contract CharityApplications is MultiSigGeneric, StorageApplications, ICharityAp AccountMessages.DepositRequest({ id: endowmentId, lockedPercentage: 100 - config.seedSplitToLiquid, - liquidPercentage: config.seedSplitToLiquid + liquidPercentage: config.seedSplitToLiquid, + donationMatch: address(this) }), config.seedAsset, config.seedAmount diff --git a/test/core/accounts/AccountsDepositWithdrawEndowments.ts b/test/core/accounts/AccountsDepositWithdrawEndowments.ts index dd920b9b9..d23b89f77 100644 --- a/test/core/accounts/AccountsDepositWithdrawEndowments.ts +++ b/test/core/accounts/AccountsDepositWithdrawEndowments.ts @@ -38,11 +38,13 @@ describe("AccountsDepositWithdrawEndowments", function () { id: charityId, liquidPercentage: 40, lockedPercentage: 60, + donationMatch: ethers.constants.AddressZero, }; const depositToNormalEndow: AccountMessages.DepositRequestStruct = { id: normalEndowId, liquidPercentage: 40, lockedPercentage: 60, + donationMatch: ethers.constants.AddressZero, }; let accOwner: SignerWithAddress; @@ -165,6 +167,7 @@ describe("AccountsDepositWithdrawEndowments", function () { id: charityId, liquidPercentage: 10, lockedPercentage: 10, + donationMatch: ethers.constants.AddressZero, }; await expect(facet.depositMatic(invalidReq, {value})).to.be.revertedWith("InvalidSplit"); }); @@ -211,7 +214,15 @@ describe("AccountsDepositWithdrawEndowments", function () { await expect( facet .connect(indexFund) - .depositMatic({id: charityId, lockedPercentage: 0, liquidPercentage: 100}, {value}) + .depositMatic( + { + id: charityId, + lockedPercentage: 0, + liquidPercentage: 100, + donationMatch: ethers.constants.AddressZero, + }, + {value} + ) ) .to.emit(facet, "EndowmentDeposit") .withArgs(charityId, wmaticFake.address, expectedLockedAmt, expectedLiquidAmt); @@ -242,7 +253,15 @@ describe("AccountsDepositWithdrawEndowments", function () { await expect( facet .connect(indexFund) - .depositMatic({id: charityId, lockedPercentage: 0, liquidPercentage: 100}, {value}) + .depositMatic( + { + id: charityId, + lockedPercentage: 0, + liquidPercentage: 100, + donationMatch: ethers.constants.AddressZero, + }, + {value} + ) ) .to.emit(facet, "EndowmentDeposit") .withArgs(charityId, wmaticFake.address, expectedLockedAmt, expectedLiquidAmt); @@ -381,7 +400,12 @@ describe("AccountsDepositWithdrawEndowments", function () { facet .connect(indexFund) .depositMatic( - {id: normalEndowId, lockedPercentage: 0, liquidPercentage: 100}, + { + id: normalEndowId, + lockedPercentage: 0, + liquidPercentage: 100, + donationMatch: ethers.constants.AddressZero, + }, {value} ) ) @@ -412,12 +436,15 @@ describe("AccountsDepositWithdrawEndowments", function () { wmaticFake.transfer.returns(true); await expect( - facet - .connect(indexFund) - .depositMatic( - {id: normalEndowId, lockedPercentage: 0, liquidPercentage: 100}, - {value} - ) + facet.connect(indexFund).depositMatic( + { + id: normalEndowId, + lockedPercentage: 0, + liquidPercentage: 100, + donationMatch: ethers.constants.AddressZero, + }, + {value} + ) ) .to.emit(facet, "EndowmentDeposit") .withArgs(normalEndowId, wmaticFake.address, expectedLockedAmt, expectedLiquidAmt); @@ -547,7 +574,15 @@ describe("AccountsDepositWithdrawEndowments", function () { const expectedLiquidAmt = BigNumber.from(1000); await expect( - facet.depositMatic({id: charityId, lockedPercentage: 0, liquidPercentage: 100}, {value}) + facet.depositMatic( + { + id: charityId, + lockedPercentage: 0, + liquidPercentage: 100, + donationMatch: ethers.constants.AddressZero, + }, + {value} + ) ) .to.emit(facet, "EndowmentDeposit") .withArgs(charityId, wmaticFake.address, expectedLockedAmt, expectedLiquidAmt); @@ -576,7 +611,15 @@ describe("AccountsDepositWithdrawEndowments", function () { wmaticFake.transfer.returns(true); await expect( - facet.depositMatic({id: charityId, lockedPercentage: 0, liquidPercentage: 100}, {value}) + facet.depositMatic( + { + id: charityId, + lockedPercentage: 0, + liquidPercentage: 100, + donationMatch: ethers.constants.AddressZero, + }, + {value} + ) ) .to.emit(facet, "EndowmentDeposit") .withArgs(charityId, wmaticFake.address, expectedLockedAmt, expectedLiquidAmt); @@ -713,7 +756,12 @@ describe("AccountsDepositWithdrawEndowments", function () { await expect( facet.depositMatic( - {id: normalEndowId, lockedPercentage: 0, liquidPercentage: 100}, + { + id: normalEndowId, + lockedPercentage: 0, + liquidPercentage: 100, + donationMatch: ethers.constants.AddressZero, + }, {value} ) ) @@ -745,7 +793,12 @@ describe("AccountsDepositWithdrawEndowments", function () { await expect( facet.depositMatic( - {id: normalEndowId, lockedPercentage: 0, liquidPercentage: 100}, + { + id: normalEndowId, + lockedPercentage: 0, + liquidPercentage: 100, + donationMatch: ethers.constants.AddressZero, + }, {value} ) ) @@ -911,6 +964,7 @@ describe("AccountsDepositWithdrawEndowments", function () { id: charityId, liquidPercentage: 10, lockedPercentage: 10, + donationMatch: ethers.constants.AddressZero, }; await expect( facet.depositERC20(invalidReq, tokenFake.address, depositAmt) @@ -950,13 +1004,16 @@ describe("AccountsDepositWithdrawEndowments", function () { const expectedLiquidAmt = BigNumber.from(depositAmt); await expect( - facet - .connect(indexFund) - .depositERC20( - {id: charityId, lockedPercentage: 0, liquidPercentage: 100}, - tokenFake.address, - depositAmt - ) + facet.connect(indexFund).depositERC20( + { + id: charityId, + lockedPercentage: 0, + liquidPercentage: 100, + donationMatch: ethers.constants.AddressZero, + }, + tokenFake.address, + depositAmt + ) ) .to.emit(facet, "EndowmentDeposit") .withArgs(charityId, tokenFake.address, expectedLockedAmt, expectedLiquidAmt); @@ -983,13 +1040,16 @@ describe("AccountsDepositWithdrawEndowments", function () { await state.setEndowmentDetails(charityId, charityBps); await expect( - facet - .connect(indexFund) - .depositERC20( - {id: charityId, lockedPercentage: 0, liquidPercentage: 100}, - tokenFake.address, - depositAmt - ) + facet.connect(indexFund).depositERC20( + { + id: charityId, + lockedPercentage: 0, + liquidPercentage: 100, + donationMatch: ethers.constants.AddressZero, + }, + tokenFake.address, + depositAmt + ) ) .to.emit(facet, "EndowmentDeposit") .withArgs(charityId, tokenFake.address, expectedLockedAmt, expectedLiquidAmt); @@ -1111,13 +1171,16 @@ describe("AccountsDepositWithdrawEndowments", function () { const expectedLiquidAmt = BigNumber.from(depositAmt); await expect( - facet - .connect(indexFund) - .depositERC20( - {id: normalEndowId, lockedPercentage: 0, liquidPercentage: 100}, - tokenFake.address, - depositAmt - ) + facet.connect(indexFund).depositERC20( + { + id: normalEndowId, + lockedPercentage: 0, + liquidPercentage: 100, + donationMatch: ethers.constants.AddressZero, + }, + tokenFake.address, + depositAmt + ) ) .to.emit(facet, "EndowmentDeposit") .withArgs(normalEndowId, tokenFake.address, expectedLockedAmt, expectedLiquidAmt); @@ -1144,13 +1207,16 @@ describe("AccountsDepositWithdrawEndowments", function () { await state.setEndowmentDetails(normalEndowId, normalEndowBps); await expect( - facet - .connect(indexFund) - .depositERC20( - {id: normalEndowId, lockedPercentage: 0, liquidPercentage: 100}, - tokenFake.address, - depositAmt - ) + facet.connect(indexFund).depositERC20( + { + id: normalEndowId, + lockedPercentage: 0, + liquidPercentage: 100, + donationMatch: ethers.constants.AddressZero, + }, + tokenFake.address, + depositAmt + ) ) .to.emit(facet, "EndowmentDeposit") .withArgs(normalEndowId, tokenFake.address, expectedLockedAmt, expectedLiquidAmt); @@ -1288,7 +1354,12 @@ describe("AccountsDepositWithdrawEndowments", function () { await expect( facet.depositERC20( - {id: charityId, lockedPercentage: 0, liquidPercentage: 100}, + { + id: charityId, + lockedPercentage: 0, + liquidPercentage: 100, + donationMatch: ethers.constants.AddressZero, + }, tokenFake.address, depositAmt ) @@ -1319,7 +1390,12 @@ describe("AccountsDepositWithdrawEndowments", function () { await expect( facet.depositERC20( - {id: charityId, lockedPercentage: 0, liquidPercentage: 100}, + { + id: charityId, + lockedPercentage: 0, + liquidPercentage: 100, + donationMatch: ethers.constants.AddressZero, + }, tokenFake.address, depositAmt ) @@ -1439,7 +1515,12 @@ describe("AccountsDepositWithdrawEndowments", function () { await expect( facet.depositERC20( - {id: normalEndowId, lockedPercentage: 0, liquidPercentage: 100}, + { + id: normalEndowId, + lockedPercentage: 0, + liquidPercentage: 100, + donationMatch: ethers.constants.AddressZero, + }, tokenFake.address, depositAmt ) @@ -1470,7 +1551,12 @@ describe("AccountsDepositWithdrawEndowments", function () { await expect( facet.depositERC20( - {id: normalEndowId, lockedPercentage: 0, liquidPercentage: 100}, + { + id: normalEndowId, + lockedPercentage: 0, + liquidPercentage: 100, + donationMatch: ethers.constants.AddressZero, + }, tokenFake.address, depositAmt )