You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Regarding contracts/payment/PullPayment.sol
You have to trust the person doing an asyncSend that he/she will not take out the amount that was promised as a payment before the withdrawal.
🐛 This is a bug report.
📝 Details
There should be some kind of insurance for the receiver that he/she will get the amount sent asynchronously.
Problem 1
It is possible to asyncSend the max value of uint256 to anyone, no check are done.
A simple solution would be to add this to the asyncSend method :
require(address(this).balance >= amount);
(Note : I know that would remove the ability to promise to withdraw as soon as there are funds later on.)
Problem 2
Using this flaw, let say you send 2 ETH to a and b. You only have 2.99 ETH, so when b withdraw first there is no problem. But when a tries to withdraw 2 ETH it fails because there is now only 1.99 ETH in the balance.
As a solution, this new require introduced earlier could check that the balance is greater than all the payments :
require(address(this).balance >= totalPayments);
Problem 3
It is possible to only withdraw 100% of the amount or nothing.
Shouldn't a be able to withdraw 1.99 at least ?
There is no priority : first arrived, first served.
The solution may require a cancellation process to avoid freezing the balance with payments that are never pulled out / withdrawn... So I'll just skip a solution proposal.
I would like to add that I know we cannot be sure the balance will stay above a certain value so these constraints may be unnecessary work.
Still, the behavior of the asyncSend should be a bit more predictable or renamed to something like maySend to avoid confusion.
The text was updated successfully, but these errors were encountered:
PullPayment could be a separate contract whose owner is a different contract PullPaymentUser. Any money sent to PullPaymentUser is redirected to PullPayment if PullPayment's balance is less than totalPayments.
For example,
contract PullPayment is Ownable {
function asyncSend() isOwner {}
}
contract PullPaymentUser {
PullPayment vault;
constructor() {
vault = new PullPayment();
}
function () payable {
if(address(vault).balance < vault.totalPayments) {
uint256 amountNeeded = vault.totalPayments.sub(address(vault).balance);
if (amountNeeded >= address(this).balance) {
address(vault).transfer(address(this).balance);
}
else {
address(vault).transfer(amountNeeded);
}
}
}
}
🎉 Description
Regarding contracts/payment/PullPayment.sol
You have to trust the person doing an
asyncSend
that he/she will not take out the amount that was promised as a payment before the withdrawal.📝 Details
There should be some kind of insurance for the receiver that he/she will get the amount sent asynchronously.
Problem 1
It is possible to
asyncSend
the max value ofuint256
to anyone, no check are done.A simple solution would be to add this to the
asyncSend
method :(Note : I know that would remove the ability to promise to withdraw as soon as there are funds later on.)
Problem 2
Using this flaw, let say you send 2 ETH to
a
andb
. You only have 2.99 ETH, so whenb
withdraw first there is no problem. But whena
tries to withdraw 2 ETH it fails because there is now only 1.99 ETH in the balance.As a solution, this new
require
introduced earlier could check that the balance is greater than all the payments :Problem 3
It is possible to only withdraw 100% of the amount or nothing.
Shouldn't
a
be able to withdraw 1.99 at least ?In
PullPayment.sol
line 23 :This could be replaced with something like :
Problem 4
There is no priority : first arrived, first served.
The solution may require a cancellation process to avoid freezing the balance with payments that are never pulled out / withdrawn... So I'll just skip a solution proposal.
I would like to add that I know we cannot be sure the balance will stay above a certain value so these constraints may be unnecessary work.
Still, the behavior of the
asyncSend
should be a bit more predictable or renamed to something likemaySend
to avoid confusion.The text was updated successfully, but these errors were encountered: