David Jay
David Jay

Reputation: 353

How can I update the price of Matic on realtime inside a smart contract

I'm working on a smart contract that allows users to pay for monthly subscriptions like Netflix, Amazon, etc...

Assuming that each subscription costs 20$ per month which is equivalent to 22 Matic at the time of writing this post.

During the time of the subscription, the user should pay 20$ per month with Matic, and its value will vary.

How can I update the monthly payment inside the smart contract so the subscriber will be able to pay each with the current value of MATIC not more not less? It's possible in solidity?

Or should I let the user pay his subscription manually each month based on the price of each subscription in dollars but with MATIC?

I tried to implement a solution with Tellor in my smart contract but I got stuck.

// smart contract subscription(part of it)
struct Subscription {
        address payable subscriber;
        uint start;
        uint nextPayment;
        bool activated;
    }

    
    /* nested mapping from address to id to Subscription */ 
    mapping(address => mapping(uint => Subscription)) private AllSubscriptions;


/* Pay subscription every Month*/
    function pay(uint256 planId) 
        external payable
        onlyUsers()
        {
        Subscription storage submitSubscription = AllSubscriptions[msg.sender][planId];

        require(block.timestamp > submitSubscription.nextPayment, " Payement not due yet");
        Plan storage plan = idToPlan[planId];

        require(msg.value >= plan.monthlyPayment, " Monthly payment not correct");

        emit PaymentSent(
            payable(msg.sender),
            payable(address(this)),
            plan.monthlyPayment,
            planId,
            block.timestamp);
        totalPaymentsPerWallet[msg.sender] += 1; 
        submitSubscription.nextPayment = submitSubscription.nextPayment + 4 weeks;

    }

// UsingTellor functionalities
// SPDX-License-Identifier: GPL-3.0
  pragma solidity ^0.8.0;

  import "usingtellor/contracts/UsingTellor.sol";

  contract PriceContract is UsingTellor {

  uint256 public btcPrice;

  //This Contract now has access to all functions in UsingTellor

  constructor(address payable _tellorAddress) UsingTellor(_tellorAddress) public {}

  function setBtcPrice() public {

    bytes memory _b = abi.encode("SpotPrice",abi.encode("MATIC","USD"));
    bytes32 _queryID = keccak256(_b);

    bool _didGet;
    uint256 _timestamp;
    bytes _value;

    (_didGet, _value, _timestamp) = getDataBefore(_queryID);

    uint256 maticPrice = abi.decode(_value,(uint256));

    require(token.transferFrom(subscriber,address(this),cost/maticPrice));
  }
}

Upvotes: -1

Views: 269

Answers (1)

Petr Hejda
Petr Hejda

Reputation: 43481

You can use any of the Chainlink data feeds that return the current price of MATIC in USD. It's a free service, there's no LINK payment for data feeds.

Docs and code example: https://docs.chain.link/docs/get-the-latest-price/

Upvotes: 1

Related Questions