Skip to content

multi token sessionkey validator [WIP]#81

Draft
kanthgithub wants to merge 6 commits into
masterfrom
feature/multi-token-sessionkey-validator
Draft

multi token sessionkey validator [WIP]#81
kanthgithub wants to merge 6 commits into
masterfrom
feature/multi-token-sessionkey-validator

Conversation

@kanthgithub

@kanthgithub kanthgithub commented Aug 25, 2024

Copy link
Copy Markdown
Collaborator

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