Skip to content

Commit

Permalink
Merge pull request #135 from PartyDAO/feat/refund-leftover-eth
Browse files Browse the repository at this point in the history
feat(`ArbitraryCallsProposal`): refund leftover ETH
  • Loading branch information
0xble authored Sep 22, 2022
2 parents 62c3b1c + abcad82 commit 1562f44
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
6 changes: 6 additions & 0 deletions contracts/proposals/ArbitraryCallsProposal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pragma solidity ^0.8;
import "../tokens/IERC721.sol";
import "../tokens/IERC721Receiver.sol";
import "../utils/LibSafeERC721.sol";
import "../utils/LibAddress.sol";

import "./LibProposal.sol";
import "./IProposalExecutionEngine.sol";
Expand All @@ -13,6 +14,7 @@ import "./IProposalExecutionEngine.sol";
// This contract will be delegatecall'ed into by `Party` proxy instances.
contract ArbitraryCallsProposal {
using LibSafeERC721 for IERC721;
using LibAddress for address payable;

struct ArbitraryCall {
// The call target.
Expand Down Expand Up @@ -87,6 +89,10 @@ contract ArbitraryCallsProposal {
}
}
}
// Refund leftover ETH.
if (ethAvailable > 0) {
payable(msg.sender).transferEth(ethAvailable);
}
// No next step, so no progressData.
return '';
}
Expand Down
24 changes: 24 additions & 0 deletions sol-tests/proposals/ArbitraryCallsProposal.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,27 @@ contract ArbitraryCallsProposalTest is
testContract.execute{ value: 1.5e18 }(prop);
}

function test_canExecuteCallWithEth_refundsLeftover() external {
(
ArbitraryCallsProposal.ArbitraryCall[] memory calls,
bytes32[] memory callArgs
) = _createSimpleCalls(1, false);
calls[0].value = 1e18;
IProposalExecutionEngine.ExecuteProposalParams memory prop =
_createTestProposal(calls);
for (uint256 i = 0; i < calls.length; ++i) {
_expectNonIndexedEmit();
emit ArbitraryCallTargetSuccessCalled(address(testContract), calls[i].value, callArgs[i]);
_expectNonIndexedEmit();
emit ArbitraryCallExecuted(prop.proposalId, i, calls.length);
}
uint256 balanceBefore = address(this).balance;
testContract.execute{ value: 2e18 }(prop);
uint256 balanceAfter = address(this).balance;
// Spent 2 ETH, refunded 1 ETH
assertEq(balanceBefore - balanceAfter, 1e18);
}

function test_cannotConsumeMoreEthThanAttachedWithSingleCall() external {
(
ArbitraryCallsProposal.ArbitraryCall[] memory calls,
Expand Down Expand Up @@ -565,4 +586,7 @@ contract ArbitraryCallsProposalTest is
mstore(data, sub(mload(data), bytesFromEnd))
}
}

// To receive ETH refunds
receive() external payable {}
}

0 comments on commit 1562f44

Please sign in to comment.