/ WalletTripMeter.sol
WalletTripMeter.sol
 1  //SPDX-License-Identifier: MIT
 2  pragma solidity ^0.8.0;
 3  
 4  import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
 5  import "OdometerInterface.sol";
 6  
 7  contract WalletTripMeter is ReentrancyGuard {
 8      address  public immutable meteredTokenAddress;
 9      mapping (address => uint256) tripMeter;
10      mapping (address => uint256) cumulativeReset;
11      mapping (address => uint256) lastReset;
12      mapping (address => uint256) resetCount;
13      event MeterReset (address wallet, uint256 resetBlock, uint256 lastReading);
14  
15      constructor (
16          address _meteredTokenAddress
17      ) {
18          meteredTokenAddress = _meteredTokenAddress;
19      }
20  
21      function readTripMeter(address tripWallet) public view returns (uint) {
22          return (OdometerInterface(meteredTokenAddress).readWalletOdometer(tripWallet) - cumulativeReset[tripWallet]);
23      }
24  
25      function resetTripMeter() external nonReentrant returns (bool){
26          bool resetComplete;
27          lastReset[msg.sender] = block.number;
28          uint meterStop = readTripMeter(msg.sender);
29          tripMeter[msg.sender] = 0;
30  
31          //  Additional check against walletOdometer. May help to protect against re-entrancy.
32          require ((cumulativeReset[msg.sender] + meterStop) == OdometerInterface(meteredTokenAddress).readWalletOdometer(msg.sender), "Fatal error: Wallet tripMeter desynchronised");
33  
34          cumulativeReset[msg.sender] = cumulativeReset[msg.sender] + meterStop;
35          resetCount[msg.sender] = resetCount[msg.sender] + 1;
36          emit MeterReset (msg.sender, lastReset[msg.sender], meterStop);
37          if (tripMeter[msg.sender] == 0) {
38              resetComplete = true;
39          }
40          return resetComplete;
41      }
42  }