Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multi token sessionkey validator [WIP] #81

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

kanthgithub
Copy link
Contributor

@kanthgithub kanthgithub commented Aug 25, 2024

MultiToken SessionKey Validator Module

Description

  • MultiTokenSessionKeyValidator Module is an advanced version of ERC20SessionKeyValidator
  • Validator Module contains multiple ERC20 tokens with a cumulative-spending Limit in USD
  • An erc7579 MultiToken SessionKey Module, which will allow a user to deploy a session key with the following constraints.
    1. select a list of assets.
    2. choose a cumulative spending limit. The cumulative spending limit must be compared to USD

Key features:

  1. allowedList of Tokens

    • Tokens allowed to be validated on the Validator

    • Tokens are initialised during deployment of SessionKeyValidator

    • OraclePriceProvider addresses should be configured for all tokens during contract constructor

    • After the Validator is deployed, AllowedList of tokens can be added/removed by owner

    • Any new tokens added to the validator should also include the OracleProviderAddress

          function addAllowedTokens(address[] memory _tokens, address[] memory _priceFeeds) external onlyOwner {
          _addAllowedTokens(_tokens, _priceFeeds);
      }
      
      function _addAllowedTokens(address[] memory _tokens, address[] memory _priceFeeds) internal {
          for (uint256 i = 0; i < _tokens.length; i++) {
              allowedTokens.add(_tokens[i]);
              priceFeeds[_tokens[i]] = IAggregatorV3Interface(_priceFeeds[i]);
          }
      }
    • OracleProviderAddress for a specific token can be updated via updatePriceFeeds

          function updatePriceFeeds(address[] memory _tokens, address[] memory _priceFeeds) external onlyOwner {
          _updatePriceFeeds(_tokens, _priceFeeds);
      }
      
      function _updatePriceFeeds(address[] memory _tokens, address[] memory _priceFeeds) internal {
          for (uint256 i = 0; i < _tokens.length; i++) {
              priceFeeds[_tokens[i]] = IAggregatorV3Interface(_priceFeeds[i]);
          }
      }
  2. CumulativeSpendingLimit (USD)

    • Spending limit in USD-Value of all tokens in the Validator
    • Limit is used to verify the total tokens spent via this validator for a sessionKey
    • SpendingLimit is managed in storage mapping for each sessionKey (sessionKey -> cumulativeSpendingLimit)
    • check on SpendingLimit is done on each validateUserOp / validateSessionKeyParams call
  3. Oracle Price Query

        function getTokenPriceInUsd(address token) internal view returns (uint256) {
    
            (, int256 price, ,uint256 updatedAt, ) = priceFeeds[token].latestRoundData();
    
            if(price == 0) {
                revert MTSKV_InvalidTokenPrice(token);
            }
    
            if(block.timestamp - updatedAt >= stalenessThresholdInSeconds) {
                revert MTSKV_StaleTokenPrice(token);
            }
    
            return uint256(price);
        }
  4. CumulativeSpendingLimit in USD estimation

           function estimateTotalSpentAmountInUsd(
      address sessionKey,
      address token,
      uint256 amount
    ) public view returns (uint256) {
      (uint256 tokenPriceUSD, uint8 feedDecimals) = getTokenPriceInUsd(token);
    
      uint8 tokenDecimals = IERC20(token).decimals();
      uint256 scaledAmount;
    
      if (tokenDecimals < USD_AMOUNT_DECIMALS) {
          // If token has fewer than 18 decimals, scale the amount up to 18 decimals
          scaledAmount = amount * (10 ** (USD_AMOUNT_DECIMALS - tokenDecimals));
      } else if(tokenDecimals > USD_AMOUNT_DECIMALS) {
          // If token has more than 18 decimals, scale the amount down to 18 decimals
          scaledAmount = amount / (10 ** (tokenDecimals - USD_AMOUNT_DECIMALS));            
      } else {
          scaledAmount = amount;
      }
    
      uint256 amountInUsd = (scaledAmount * tokenPriceUSD) / (10 ** feedDecimals);
    
      // add the amountInUsd with the totalSpentInUsd for the session key
      return amountInUsd + totalSpentInUsd[sessionKey];
    }
    
        function checkSpendingLimit(address sessionKey, address user, address token, uint256 amount) public view returns (bool) {
            MultiTokenSessionData memory data = multiTokenSessionData[sessionKey][user];
            return estimateTotalSpentAmountInUsd(sessionKey, token, amount) <= data.cumulativeSpendingLimitInUsd;
        }

How Has This Been Tested?

Types of changes

  • New feature (non-breaking change which adds functionality)

@kanthgithub kanthgithub changed the title Feature/multi token sessionkey validator multi token sessionkey validator Aug 25, 2024
@kanthgithub kanthgithub self-assigned this Aug 25, 2024
@kanthgithub kanthgithub added the enhancement New feature or request label Aug 25, 2024
@kanthgithub kanthgithub changed the title multi token sessionkey validator multi token sessionkey validator [WIP] Aug 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Development

Successfully merging this pull request may close these issues.

1 participant