Skip to content

Commit

Permalink
added price expiry duration
Browse files Browse the repository at this point in the history
  • Loading branch information
ShivaanshK committed Sep 9, 2024
1 parent 06f93ff commit e747ec7
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 15 deletions.
5 changes: 5 additions & 0 deletions contracts/common/BiconomyTokenPaymasterErrors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,9 @@ contract BiconomyTokenPaymasterErrors {
* @notice Throws when oracle returns invalid price
*/
error OraclePriceNotPositive();

/**
* @notice Throws when oracle price hasn't been updated for a duration of time the owner is comfortable with
*/
error OraclePriceExpired();
}
9 changes: 6 additions & 3 deletions contracts/interfaces/IBiconomyTokenPaymaster.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ interface IBiconomyTokenPaymaster {
uint8 decimals;
}

event UnaccountedGasChanged(uint256 indexed oldValue, uint256 indexed newValue);
event FixedDynamicAdjustmentChanged(uint256 indexed oldValue, uint256 indexed newValue);
event FeeCollectorChanged(address indexed oldFeeCollector, address indexed newFeeCollector, address indexed actor);
event UpdatedUnaccountedGas(uint256 indexed oldValue, uint256 indexed newValue);
event UpdatedFixedDynamicAdjustment(uint256 indexed oldValue, uint256 indexed newValue);
event UpdatedFeeCollector(address indexed oldFeeCollector, address indexed newFeeCollector, address indexed actor);
event UpdatedPriceExpiryDuration(uint256 indexed oldValue, uint256 indexed newValue);
event GasDeposited(address indexed paymasterId, uint256 indexed value);
event GasWithdrawn(address indexed paymasterId, address indexed to, uint256 indexed value);
event GasBalanceDeducted(address indexed paymasterId, uint256 indexed charge, bytes32 indexed userOpHash);
Expand All @@ -27,5 +28,7 @@ interface IBiconomyTokenPaymaster {

function setDynamicAdjustment(uint256 _newUnaccountedGas) external payable;

function setPriceExpiryDuration(uint256 _newPriceExpiryDuration) external payable;

function setTokenInfo(address _tokenAddress, IOracle _oracle, uint8 _decimals) external payable;
}
42 changes: 30 additions & 12 deletions contracts/token/BiconomyTokenPaymaster.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ import "@account-abstraction/contracts/core/Helpers.sol";
* @author ShivaanshK<[email protected]>
* @author livingrockrises<[email protected]>
* @notice Token Paymaster for Entry Point v0.7
* @dev A paymaster that allows user to pay gas fees in ERC20 tokens. The paymaster owner chooses which tokens to
* accept. The payment manager (usually the owner) first deposits native gas into the EntryPoint. Then, for each
* transaction, it takes the gas fee from the user's ERC20 token balance. The exchange rate between ETH and the token is
* calculated using 1 of three methods: external price source, off-chain oracle, or a TWAP oracle.
* @dev A paymaster that allows user to pay gas fees in ERC20 tokens. The paymaster uses the precharge and refund model
* to handle gas remittances. For fair and "always available" operation, it relies on price oracles which
* implement the IOracle interface to calculate the gas cost of the transaction in a supported token. The owner has full
* discretion over the supported tokens, premium and discounts applied (if any), and how to manage the assets
* received by the paymaster. The properties described above, make the paymaster self-relaint: independent of any
* offchain service for use.
*/
contract BiconomyTokenPaymaster is
BasePaymaster,
Expand All @@ -34,20 +36,22 @@ contract BiconomyTokenPaymaster is
address public feeCollector;
uint256 public unaccountedGas;
uint256 public dynamicAdjustment;
uint256 public priceExpiryDuration;
IOracle public nativeOracle; // ETH -> USD price
mapping(address => TokenInfo) tokenDirectory;

// Limit for unaccounted gas cost
uint256 private constant UNACCOUNTED_GAS_LIMIT = 50_000;
uint256 private constant PRICE_DENOMINATOR = 1e6;
uint256 private constant MAX_DYNAMIC_ADJUSTMENT = 2e6;
uint256 private constant MAX_DYNAMIC_ADJUSTMENT = 2e6; // 100% premium on price (2e6/PRICE_DENOMINATOR)

constructor(
address _owner,
IEntryPoint _entryPoint,
uint256 _unaccountedGas,
uint256 _dynamicAdjustment,
IOracle _nativeOracle,
uint256 _priceExpiryDuration,
address[] memory _tokens, // Array of token addresses
uint8[] memory _decimals, // Array of corresponding token decimals
IOracle[] memory _oracles // Array of corresponding oracle addresses
Expand Down Expand Up @@ -176,7 +180,7 @@ contract BiconomyTokenPaymaster is
assembly ("memory-safe") {
sstore(feeCollector.slot, _newFeeCollector)
}
emit FeeCollectorChanged(oldFeeCollector, _newFeeCollector, msg.sender);
emit UpdatedFeeCollector(oldFeeCollector, _newFeeCollector, msg.sender);
}

/**
Expand All @@ -192,12 +196,12 @@ contract BiconomyTokenPaymaster is
assembly ("memory-safe") {
sstore(unaccountedGas.slot, _newUnaccountedGas)
}
emit UnaccountedGasChanged(oldUnaccountedGas, _newUnaccountedGas);
emit UpdatedUnaccountedGas(oldUnaccountedGas, _newUnaccountedGas);
}

/**
* @dev Set a new dynamicAdjustment value.
* @param _newDynamicAdjustment The new value to be set as the unaccounted gas value
* @param _newDynamicAdjustment The new value to be set as the dynamic adjustment
* @notice only to be called by the owner of the contract.
*/
function setDynamicAdjustment(uint256 _newDynamicAdjustment) external payable override onlyOwner {
Expand All @@ -208,7 +212,20 @@ contract BiconomyTokenPaymaster is
assembly ("memory-safe") {
sstore(dynamicAdjustment.slot, _newDynamicAdjustment)
}
emit FixedDynamicAdjustmentChanged(oldDynamicAdjustment, _newDynamicAdjustment);
emit UpdatedFixedDynamicAdjustment(oldDynamicAdjustment, _newDynamicAdjustment);
}

/**
* @dev Set a new dynamicAdjustment value.
* @param _newPriceExpiryDuration The new value to be set as the unaccounted gas value
* @notice only to be called by the owner of the contract.
*/
function setPriceExpiryDuration(uint256 _newPriceExpiryDuration) external payable override onlyOwner {
uint256 oldPriceExpiryDuration = priceExpiryDuration;
assembly ("memory-safe") {
sstore(priceExpiryDuration.slot, _newPriceExpiryDuration)
}
emit UpdatedPriceExpiryDuration(oldPriceExpiryDuration, _newPriceExpiryDuration);
}

/**
Expand All @@ -229,6 +246,7 @@ contract BiconomyTokenPaymaster is
onlyOwner
{
tokenDirectory[_tokenAddress] = TokenInfo(_oracle, _decimals);
emit UpdatedTokenDirectory(_tokenAddress, _oracle, _decimals);
}

/**
Expand Down Expand Up @@ -293,9 +311,9 @@ contract BiconomyTokenPaymaster is
if (answer <= 0) {
revert OraclePriceNotPositive();
}
// if (updatedAt < block.timestamp - stalenessThreshold) {
// revert OraclePriceStale();
// }
if (updatedAt < block.timestamp - priceExpiryDuration) {
revert OraclePriceExpired();
}
price = uint192(int192(answer));
}
}

0 comments on commit e747ec7

Please sign in to comment.