/ CallerTripMeter.sol
CallerTripMeter.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 CallerTripMeter is ReentrancyGuard {
 8      address public immutable meteredTokenAddress;
 9      mapping (address => mapping (address => uint256)) callerTripMeter;
10      mapping (address => mapping (address => uint256)) callerCumulativeReset;
11      mapping (address => mapping (address => uint256)) callerLastReset;
12      mapping (address => mapping (address => uint256)) callerResetCount;
13      event CallerMeterReset (address wallet, address caller, uint256 resetBlock, uint256 lastReading);
14  
15      constructor (
16          address _meteredTokenAddress
17      ) {
18          meteredTokenAddress = _meteredTokenAddress;
19      }
20  
21      function readCallerTripMeter(address tripWallet) public view returns (uint) {
22          return (OdometerInterface(meteredTokenAddress).readWalletOdometer(tripWallet) - callerCumulativeReset[msg.sender][tripWallet]);
23      }
24  
25      function readCalledTripMeter (address callAddress, address tripWallet) public view returns (uint256) {
26          return (OdometerInterface(meteredTokenAddress).readWalletOdometer(tripWallet) - callerCumulativeReset[callAddress][tripWallet]);
27      }
28  
29      function checkLastCallerReset (address callAddress, address tripWallet) public view returns (uint256)  {
30          return (callerLastReset[callAddress][tripWallet]);
31      }
32  
33      function resetCallerTripMeter(address resetWallet) external nonReentrant returns (bool){
34          bool callerResetComplete;
35          callerLastReset[msg.sender][resetWallet] = block.number;
36          uint callerMeterStop = readCallerTripMeter(resetWallet);
37          callerTripMeter[msg.sender][resetWallet] = 0;
38  
39          //  Additional check against walletOdometer. May help to protect against re-entrancy.
40          require ((callerCumulativeReset[msg.sender][resetWallet] + callerMeterStop) == OdometerInterface(meteredTokenAddress).readWalletOdometer(msg.sender), "Fatal error: callerTripMeter desynchronised");
41  
42          callerCumulativeReset[msg.sender][resetWallet] = callerCumulativeReset[msg.sender][resetWallet] + callerMeterStop;
43          callerResetCount[msg.sender][resetWallet] = callerResetCount[msg.sender][resetWallet] + 1;
44          emit CallerMeterReset (resetWallet, msg.sender, callerLastReset[msg.sender][resetWallet], callerMeterStop);
45          if (callerTripMeter[msg.sender][resetWallet] == 0) {
46              callerResetComplete = true;
47          }
48          return callerResetComplete;
49      }
50  
51  }