Hello bounty hunters,
Gitcoin Grants is a platform to fund your open source work with recurring payments. We've developed Gitcoin Grants so that OSS Developers can crowdsource funding for the awesome work they are already doing and allow companies to provide more significant recurring funding for contributions on their open source repos.
The task is to find security vulnerabilities in our Subscription smart contract. A security vulnerability is any issue that impacts the well-being of the end-user on the platform. Compensation will not be provided for visual, optmization, or interface issues.
The contract can be found at https://github.com/gitcoinco/grants1337/blob/master/Subscription/Subscription.sol. The dependencies are solidity.
Unfotunately, we do not have a truffle test suite written. We need to implement a listener in the main app in order to do so, but hope to have one up soon.

Payouts are structured according to the severity of the security issue raised. See aforementioned OWASP model for more info.
We may receive many responses before being able to implement changes, because of this payouts will be for bugs that are unknown to us at the time of notification.
Please email any findings to [email protected].
Issue Status: 1. Open 2. Started 3. Submitted 4. Done
__This issue now has a funding of 2.5 ETH (521.69 USD @ $208.67/ETH) attached to it as part of the Gitcoin fund.__
Issue Status: 1. Open 2. Started 3. Submitted 4. Done
__This issue now has a funding of 2.5 ETH (521.69 USD @ $208.67/ETH) attached to it as part of the Gitcoin fund.__
Issue Status: 1. Open 2. Started 3. Submitted 4. Done
__Work has been started__.
These users each claimed they can complete the work by 7Â months, 2Â weeks from now.
Please review their action plans below:
1) liamzebedee has started work.
I will detail any vulnerability I find in detail with example code for suitable reproducibility.
Learn more on the Gitcoin Issue Details page.
Found some stuff - but will email and not comment here? Is that what is requested? :)
@liamzebedee email [email protected] ?
Where do we need to find-out vulnerability? I mean what is in scope? I can start finding in gitcoin.co ? or only https://tokensubscription.com? @owocki
@6ug From above: The task is to find security vulnerabilities in our Subscription smart contract. A security vulnerability is any issue that impacts the well-being of the end-user on the platform. Compensation will not be provided for visual, optmization, or interface issues.
The contract can be found at https://github.com/gitcoinco/grants1337/blob/master/Subscription/Subscription.sol. The dependencies are solidity.
Also, please note: We may receive many responses before being able to implement changes, because of this payouts will be for bugs that are unknown to us at the time of notification.
Response to Timur Badretdinov:
Also, this solution gives the benefit to the provider if they forget to process a transaction. It allows them to reset the timestamp based off of the second the last period ended, instead of the second the transactions is processed. I can see why someone would want to implement this way. I would prefer giving the benefit to the subscriber. If I forget to process your transaction, you should get free service during that time. Also, when there is a network of subminers processing transactions, the economic incentive is to process the transaction as soon as possible or another subminer will do it before you.
I suppose though, since we have isSubscriptionActive we might want to implement with nextValidTimestamp as suggested. To be paid .25 ETH from Gitcoin funds, .25 from 1337 funds
getSubscriptionHash() than in isSubscriptionReady() though. That way you cant even create the subscription if it does not meet the requirements of the creator. Low Impact bug, more of a code refactor suggestion. To be paid from Gitcoin .125 ETH, .125 from 1337require(from == msg.sender, 'msg.sender is not the subscriber') in cancelSubscription. Oops. Critical bug. 1.25 ETH From Gitcoin, 1.25 from 1337 mapping(bytes32 => bool) public subHashStatus and either implement require() statements where needed or isCancelled as suggested. Medium impact bug with high likelihood. To be paid .875 from Gitcoin .875 from 1337@owocki please pay out 2.5 ETH from Gitcoin, and 3 ETH from the 1337 ECF grant.
Responding to @liamzebedee :
Since a contract’s address is based on the deployed ABI of the contract, but not the contract’s storage, an attack vector I’ve decided to exploit is creating a contract which adheres to the ERC20 interface but whose functionality can be changed to the Subscription contract’s direct disadvantage.
The Subscription contract uses the return value of ERC20.transferFrom to ascertain whether executeSubscription was successful. The token address of Subscription cannot be changed, but the underlying contract can.
The example attached is a proxy contract using delegate call. The first contract can function like a real ERC20 token, only later to be replaced with one which always returns true from transferFrom.
Solutions: A possible fix would be to check the balance before and after, rather than relying on the value of transferFrom.
Exploit mechanism: Re-entrancy attacks
If the ERC20.transferFrom call is re-entrant, meaning it will maliciously call back into the Subscription, it is possible to exploit some facts:
//increment the timestamp by the period so it wont be valid until then
nextValidTimestamp[subscriptionHash] = block.timestamp.add(periodSeconds);
This is executed before transferFrom - so a malicious actor (who specifically has engineered their own proxy contract to with a valid nonce/sig for re-entrant calls) can effectively extend their subscription period by periodSeconds every call. Infinite Netflix anyone?
.transferFrom(), but we have a require() statement on ln228 of the bounties version that checks the validity of the timestamp on each transaction. Unless I misunderstand reentrancy bug 🤷‍♂️ . There will be no pay out for this comment. Example code for proxy contract is here.
https://gist.github.com/liamzebedee/5c2afd3a24bb840744ab9cf149055738
@owocki please pay out 1.75 ETH from the 1337 ECF Grant to @liamzebedee he is a bounty hunter on the gitcoin bounty: https://gitcoin.co/issue/gitcoinco/web/2480/1553
Hey @captnseagraves - not sure where the communication faltered - but on the Slack channel we discussed the re-entrancy attack. I agreed that it wasn't re-entrant, however there was still a vulnerability in terms of how signature validation did not fail when it should. Otherwise, thank you for the payout. I'll hit you up on Slack :)
i will pay this out as soon as i get november's ETH from consensys finance
⚡️ A tip worth 1.75000 ETH (374.22 USD @ $213.84/ETH) has been granted to @liamzebedee for this issue from @owocki. ⚡️
The sender had the following public comments:
Thanks for your help with the secrurity audit!
Nice work @liamzebedee! Your tip has automatically been deposited in the ETH address we have on file.
⚡️ A tip worth 3.00000 ETH (641.53 USD @ $213.84/ETH) has been granted to @Destiner for this issue from @owocki. ⚡️
The sender had the following public comments:
Thank you!
Nice work @Destiner! Your tip has automatically been deposited in the ETH address we have on file.
⚡️ A tip worth 2.50000 ETH (534.61 USD @ $213.84/ETH) has been granted to @Destiner for this issue from @owocki. ⚡️
The sender had the following public comments:
thanks again!
Nice work @Destiner! Your tip has automatically been deposited in the ETH address we have on file.