0

I'm working on a smart contract that allows users to pay for monthly subscriptions depending on the plans that they choose. I deployed the smart contract on Polygon mainnet using remix IDE. when I created the plan using createPlan function with USDT/Polygon, then I triggered the function subscribe to pay subscription using USDT (https://polygonscan.com/token/0xc2132d05d31c914a87c6611c10748aeb04b58e8f) That I have in my wallet I got this error message :

enter image description here

pragma solidity ^0.8.10;

import '@openzeppelin/contracts/token/ERC20/IERC20.sol';

contract Payment { uint public nextPlanId; struct Plan { address merchant; address token; uint amount; uint frequency; } struct Subscription { address subscriber; uint start; uint nextPayment; } mapping(uint => Plan) public plans; mapping(address => mapping(uint => Subscription)) public subscriptions;

event PlanCreated( address merchant, uint planId, uint date ); event SubscriptionCreated( address subscriber, uint planId, uint date ); event SubscriptionCancelled( address subscriber, uint planId, uint date ); event PaymentSent( address from, address to, uint amount, uint planId, uint date );

function createPlan(address token, uint amount, uint frequency) external { require(token != address(0), 'address cannot be null address'); require(amount > 0, 'amount needs to be > 0'); require(frequency > 0, 'frequency needs to be > 0'); plans[nextPlanId] = Plan( msg.sender, token, amount, frequency ); nextPlanId++; }

function subscribe(uint planId) external { IERC20 token = IERC20(plans[planId].token); Plan storage plan = plans[planId]; require(plan.merchant != address(0), 'this plan does not exist'); token.approve(address(this), plan.amount); token.transferFrom(msg.sender, plan.merchant, plan.amount);
emit PaymentSent( msg.sender, plan.merchant, plan.amount, planId, block.timestamp );

subscriptions[msg.sender][planId] = Subscription(
  msg.sender, 
  block.timestamp, 
  block.timestamp + plan.frequency
);
emit SubscriptionCreated(msg.sender, planId, block.timestamp);

}

How can solve this? Am I using the wrong USDT address? Thank you

David Jay
  • 301
  • 1
  • 8
  • 1
    Make sure to read the ERC-20 standard. The end user needs to approve the contract to spend their tokens before the contract is able to call transferFrom. – Paul Razvan Berg Jun 15 '22 at 21:04
  • I edited my post, I added token.approve(address(this),plan.amount) I tested the smart contract but I got the same error, I was thinking if I use async await inside my React App I should wait for the token.approve to be confirmed then trigger transferfrom – David Jay Jun 15 '22 at 21:11
  • 1
    @DavidJay A contract cannot approve itself, it is the user that has to call approve, see this question for an explanation https://ethereum.stackexchange.com/questions/46457/send-tokens-using-approve-and-transferfrom-vs-only-transfer. – Ismael Jun 16 '22 at 20:00

0 Answers0