diff --git a/lib/forge-std b/lib/forge-std index e4aef94c1..5a802d7c1 160000 --- a/lib/forge-std +++ b/lib/forge-std @@ -1 +1 @@ -Subproject commit e4aef94c1768803a16fe19f7ce8b65defd027cfd +Subproject commit 5a802d7c10abb4bbfb3e7214c75052ef9e6a06f8 diff --git a/lib/openzeppelin-contracts b/lib/openzeppelin-contracts index bd325d56b..0a25c1940 160000 --- a/lib/openzeppelin-contracts +++ b/lib/openzeppelin-contracts @@ -1 +1 @@ -Subproject commit bd325d56b4c62c9c5c1aff048c37c6bb18ac0290 +Subproject commit 0a25c1940ca220686588c4af3ec526f725fe2582 diff --git a/lib/openzeppelin-contracts-upgradeable b/lib/openzeppelin-contracts-upgradeable index 723f8cab0..f231c5cb8 160000 --- a/lib/openzeppelin-contracts-upgradeable +++ b/lib/openzeppelin-contracts-upgradeable @@ -1 +1 @@ -Subproject commit 723f8cab09cdae1aca9ec9cc1cfa040c2d4b06c1 +Subproject commit f231c5cb86c0c045dc0b23d8f3beeaf0d68dccc7 diff --git a/lib/redstone-oracles-monorepo b/lib/redstone-oracles-monorepo index 223d13e3e..97e00b4e9 160000 --- a/lib/redstone-oracles-monorepo +++ b/lib/redstone-oracles-monorepo @@ -1 +1 @@ -Subproject commit 223d13e3ef3646e9ce4250d227992fed13a70a97 +Subproject commit 97e00b4e9928061543be0fbe03bac4415430eb0f diff --git a/lib/solady b/lib/solady index bb4b43b44..42af395e6 160000 --- a/lib/solady +++ b/lib/solady @@ -1 +1 @@ -Subproject commit bb4b43b44bec3c5d42604c08904bca0442e0bc78 +Subproject commit 42af395e631fcc9d640eddf11c57c6f1ca3f9103 diff --git a/src/contracts/atlas/Factory.sol b/src/contracts/atlas/Factory.sol index 8766bd573..ba5c5fc5a 100644 --- a/src/contracts/atlas/Factory.sol +++ b/src/contracts/atlas/Factory.sol @@ -62,9 +62,7 @@ abstract contract Factory { /// @param userOp The user operation containing details about the user and the DAppControl contract. /// @return executionEnvironment The address of the execution environment that was found or created. /// @return dConfig The DAppConfig for the execution environment, specifying how operations should be handled. - function _getOrCreateExecutionEnvironment( - UserOperation calldata userOp - ) + function _getOrCreateExecutionEnvironment(UserOperation calldata userOp) internal returns (address executionEnvironment, DAppConfig memory dConfig) { diff --git a/src/contracts/atlas/Storage.sol b/src/contracts/atlas/Storage.sol index 416bb124d..4a20052b1 100644 --- a/src/contracts/atlas/Storage.sol +++ b/src/contracts/atlas/Storage.sol @@ -87,9 +87,7 @@ contract Storage is AtlasEvents, AtlasErrors, AtlasConstants { return S_bondedTotalSupply; } - function accessData( - address account - ) + function accessData(address account) external view returns ( diff --git a/src/contracts/common/ExecutionEnvironment.sol b/src/contracts/common/ExecutionEnvironment.sol index 48bebfadd..b818e2c22 100644 --- a/src/contracts/common/ExecutionEnvironment.sol +++ b/src/contracts/common/ExecutionEnvironment.sol @@ -40,9 +40,7 @@ contract ExecutionEnvironment is Base { /// corresponding `preOpsCall` function. /// @param userOp The UserOperation struct. /// @return preOpsData Data to be passed to the next call phase. - function preOpsWrapper( - UserOperation calldata userOp - ) + function preOpsWrapper(UserOperation calldata userOp) external validUser(userOp) onlyAtlasEnvironment @@ -64,9 +62,7 @@ contract ExecutionEnvironment is Base { /// with `userOp.data` as calldata, depending on the the needsDelegateUser flag. /// @param userOp The UserOperation struct. /// @return returnData Data to be passed to the next call phase. - function userWrapper( - UserOperation calldata userOp - ) + function userWrapper(UserOperation calldata userOp) external payable validUser(userOp) diff --git a/src/contracts/dapp/DAppControl.sol b/src/contracts/dapp/DAppControl.sol index 4095413d1..6cf5fa25d 100644 --- a/src/contracts/dapp/DAppControl.sol +++ b/src/contracts/dapp/DAppControl.sol @@ -63,9 +63,7 @@ abstract contract DAppControl is DAppControlTemplate, ExecutionBase { /// @notice The preOpsCall hook which may be called before the UserOperation is executed. /// @param userOp The UserOperation struct. /// @return data Data to be passed to the next call phase. - function preOpsCall( - UserOperation calldata userOp - ) + function preOpsCall(UserOperation calldata userOp) external payable validControl @@ -164,9 +162,7 @@ abstract contract DAppControl is DAppControlTemplate, ExecutionBase { /// @notice Returns the DAppConfig struct of this DAppControl contract. /// @param userOp The UserOperation struct. /// @return dConfig The DAppConfig struct of this DAppControl contract. - function getDAppConfig( - UserOperation calldata userOp - ) + function getDAppConfig(UserOperation calldata userOp) external view mustBeCalled diff --git a/src/contracts/examples/ex-post-mev-example/V2ExPost.sol b/src/contracts/examples/ex-post-mev-example/V2ExPost.sol index cd1f41c1a..6d7bb4948 100644 --- a/src/contracts/examples/ex-post-mev-example/V2ExPost.sol +++ b/src/contracts/examples/ex-post-mev-example/V2ExPost.sol @@ -37,9 +37,7 @@ contract V2ExPost is DAppControl { event GiftedGovernanceToken(address indexed user, address indexed token, uint256 amount); - constructor( - address _atlas - ) + constructor(address _atlas) DAppControl( _atlas, msg.sender, diff --git a/src/contracts/examples/gas-filler/Filler.sol b/src/contracts/examples/gas-filler/Filler.sol index 93deb83f7..a0e9ee643 100644 --- a/src/contracts/examples/gas-filler/Filler.sol +++ b/src/contracts/examples/gas-filler/Filler.sol @@ -269,9 +269,7 @@ contract Filler is DAppControl { delete prepaid; } - function _decodeRawData( - bytes calldata data - ) + function _decodeRawData(bytes calldata data) internal pure returns (uint256 gasNeeded, ApprovalTx memory approvalTx) diff --git a/src/contracts/examples/intents-example/SwapIntentDAppControl.sol b/src/contracts/examples/intents-example/SwapIntentDAppControl.sol index ca295009d..8aabc1b1c 100644 --- a/src/contracts/examples/intents-example/SwapIntentDAppControl.sol +++ b/src/contracts/examples/intents-example/SwapIntentDAppControl.sol @@ -40,9 +40,7 @@ contract SwapIntentDAppControl is DAppControl { uint256 public constant USER_CONDITION_GAS_LIMIT = 20_000; uint256 public constant MAX_USER_CONDITIONS = 5; - constructor( - address _atlas - ) + constructor(address _atlas) DAppControl( _atlas, msg.sender, diff --git a/src/contracts/examples/intents-example/V4SwapIntent.sol b/src/contracts/examples/intents-example/V4SwapIntent.sol index d9ef5a777..46c6f2775 100644 --- a/src/contracts/examples/intents-example/V4SwapIntent.sol +++ b/src/contracts/examples/intents-example/V4SwapIntent.sol @@ -103,9 +103,7 @@ contract V4SwapIntentControl is DAppControl { } // selector 0x04e45aaf - function exactInputSingle( - ExactInputSingleParams calldata params - ) + function exactInputSingle(ExactInputSingleParams calldata params) external payable verifyCall(params.tokenIn, params.tokenOut, params.amountIn) @@ -133,9 +131,7 @@ contract V4SwapIntentControl is DAppControl { } // selector 0x5023b4df - function exactOutputSingle( - ExactOutputSingleParams calldata params - ) + function exactOutputSingle(ExactOutputSingleParams calldata params) external payable verifyCall(params.tokenIn, params.tokenOut, params.amountInMaximum) diff --git a/src/contracts/examples/oev-example/ChainlinkAtlasWrapper.sol b/src/contracts/examples/oev-example/ChainlinkAtlasWrapper.sol index 807ecf8ed..50ab45579 100644 --- a/src/contracts/examples/oev-example/ChainlinkAtlasWrapper.sol +++ b/src/contracts/examples/oev-example/ChainlinkAtlasWrapper.sol @@ -172,9 +172,7 @@ contract ChainlinkAtlasWrapper is Ownable, IChainlinkAtlasWrapper { } // Pass-through call to base oracle's `getRoundData()` function - function getRoundData( - uint80 _roundId - ) + function getRoundData(uint80 _roundId) external view override diff --git a/src/contracts/examples/oev-example/ChainlinkDAppControl.sol b/src/contracts/examples/oev-example/ChainlinkDAppControl.sol index d7eb555e6..c13bcd6ea 100644 --- a/src/contracts/examples/oev-example/ChainlinkDAppControl.sol +++ b/src/contracts/examples/oev-example/ChainlinkDAppControl.sol @@ -53,9 +53,7 @@ contract ChainlinkDAppControl is DAppControl { event SignerRemovedForBaseFeed(address indexed baseFeed, address indexed signer); event ObservationsQuorumSet(uint256 oldQuorum, uint256 newQuorum); - constructor( - address _atlas - ) + constructor(address _atlas) DAppControl( _atlas, msg.sender, diff --git a/src/contracts/examples/oev-example/ChainlinkDAppControlAlt.sol b/src/contracts/examples/oev-example/ChainlinkDAppControlAlt.sol index 6b6599b9c..d518c4eb4 100644 --- a/src/contracts/examples/oev-example/ChainlinkDAppControlAlt.sol +++ b/src/contracts/examples/oev-example/ChainlinkDAppControlAlt.sol @@ -49,9 +49,7 @@ contract ChainlinkDAppControl is DAppControl { event SignerAddedForBaseFeed(address indexed baseFeed, address indexed signer); event SignerRemovedForBaseFeed(address indexed baseFeed, address indexed signer); - constructor( - address _atlas - ) + constructor(address _atlas) DAppControl( _atlas, msg.sender, diff --git a/src/contracts/examples/oev-example/IChainlinkAtlasWrapper.sol b/src/contracts/examples/oev-example/IChainlinkAtlasWrapper.sol index f46b40860..a45b6e7b8 100644 --- a/src/contracts/examples/oev-example/IChainlinkAtlasWrapper.sol +++ b/src/contracts/examples/oev-example/IChainlinkAtlasWrapper.sol @@ -22,9 +22,7 @@ interface AggregatorV3Interface { // getRoundData and latestRoundData should both raise "No data present" // if they do not have data to report, instead of returning unset values // which could be misinterpreted as actual reported values. - function getRoundData( - uint80 _roundId - ) + function getRoundData(uint80 _roundId) external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); diff --git a/src/contracts/examples/redstone-oev/RedstoneDAppControl.sol b/src/contracts/examples/redstone-oev/RedstoneDAppControl.sol index 603e39382..e783af1eb 100644 --- a/src/contracts/examples/redstone-oev/RedstoneDAppControl.sol +++ b/src/contracts/examples/redstone-oev/RedstoneDAppControl.sol @@ -24,9 +24,7 @@ contract RedstoneDAppControl is DAppControl { mapping(address bundler => bool isWhitelisted) public bundlerWhitelist; uint32 public NUM_WHITELISTED_BUNDLERS = 0; - constructor( - address _atlas - ) + constructor(address _atlas) DAppControl( _atlas, msg.sender, diff --git a/src/contracts/examples/redstone-oev/RedstoneOevDappControl.sol b/src/contracts/examples/redstone-oev/RedstoneOevDappControl.sol index 623cc08f6..da2f73cf3 100644 --- a/src/contracts/examples/redstone-oev/RedstoneOevDappControl.sol +++ b/src/contracts/examples/redstone-oev/RedstoneOevDappControl.sol @@ -3,45 +3,58 @@ pragma solidity 0.8.25; import { DAppControl } from "src/contracts/dapp/DAppControl.sol"; import { CallConfig } from "src/contracts/types/ConfigTypes.sol"; +import { SafeTransferLib } from "solady/utils/SafeTransferLib.sol"; +import { IRedstoneAdapter } from + "lib/redstone-oracles-monorepo/packages/on-chain-relayer/contracts/core/IRedstoneAdapter.sol"; + import "src/contracts/types/UserOperation.sol"; import "src/contracts/types/SolverOperation.sol"; -import "./RedstoneAdapterAtlasWrapper.sol"; -import { SafeTransferLib } from "solady/utils/SafeTransferLib.sol"; contract RedstoneOevDappControl is DAppControl { - error FailedToAllocateOEV(); error OnlyGovernance(); error OnlyWhitelistedBundlerAllowed(); + error OnlyWhitelistedOracleAllowed(); + error InvalidUserDestination(); + error InvalidUserEntryCall(); + error InvalidUserUpdateCall(); error OracleUpdateFailed(); + error InvalidOevShare(); + error InvalidOevAllocationDestination(); - uint256 public bundlerOEVPercent; - uint256 public atlasOEVPercent; - address public atlasVault; - mapping(address oracle => address oracleVault) public oracleVaults; + uint256 public constant OEV_SHARE_SCALE = 10_000; + + // OEV shares are in hundredth of percent + uint256 public oevShareBundler; + uint256 public oevShareFastlane; + + address public oevAllocationDestination; mapping(address bundler => bool isWhitelisted) public bundlerWhitelist; - uint32 public NUM_WHITELISTED_BUNDLERS = 0; + uint32 public whitelistedBundlersCount = 0; + + mapping(address oracle => bool isWhitelisted) public oracleWhitelist; + uint32 public whitelistedOraclesCount = 0; constructor( - address _atlas, - address _atlasVault, - uint256 _bundlerOEVPercent, - uint256 _atlasOEVPercent + address atlas, + uint256 oevShareBundler_, + uint256 oevShareFastlane_, + address oevAllocationDestination_ ) DAppControl( - _atlas, + atlas, msg.sender, CallConfig({ userNoncesSequential: false, dappNoncesSequential: false, - requirePreOps: false, + requirePreOps: true, trackPreOpsReturnData: false, - trackUserReturnData: true, + trackUserReturnData: false, delegateUser: false, requirePreSolver: false, requirePostSolver: false, requirePostOps: false, - zeroSolvers: true, // oracle updates can be made without solvers and no OEV + zeroSolvers: true, // Oracle updates can be made without solvers and no OEV reuseUserOp: true, userAuctioneer: true, solverAuctioneer: false, @@ -52,95 +65,166 @@ contract RedstoneOevDappControl is DAppControl { trustedOpHash: false, invertBidValue: false, exPostBids: false, - allowAllocateValueFailure: true // oracle updates should go through even if OEV allocation fails + allowAllocateValueFailure: true // Oracle updates should go through even if OEV allocation fails }) ) { - bundlerOEVPercent = _bundlerOEVPercent; - atlasOEVPercent = _atlasOEVPercent; - atlasVault = _atlasVault; + if (oevShareBundler_ + oevShareFastlane_ > OEV_SHARE_SCALE) revert InvalidOevShare(); + if (oevAllocationDestination_ == address(0)) revert InvalidOevAllocationDestination(); + + oevShareBundler = oevShareBundler_; + oevShareFastlane = oevShareFastlane_; + oevAllocationDestination = oevAllocationDestination_; + } + + // ---------------------------------------------------- // + // Custom Functions // + // ---------------------------------------------------- // + + modifier onlyGov() { + if (msg.sender != governance) revert OnlyGovernance(); + _; } - function setBundlerOEVPercent(uint256 _bundlerOEVPercent) external onlyGov { - require(_bundlerOEVPercent + atlasOEVPercent <= 100, "Invalid OEV percent"); - bundlerOEVPercent = _bundlerOEVPercent; + function setOevShareBundler(uint256 oevShareBundler_) external onlyGov { + if (oevShareBundler_ + oevShareFastlane > OEV_SHARE_SCALE) revert InvalidOevShare(); + oevShareBundler = oevShareBundler_; } - function setAtlasOEVPercent(uint256 _atlasOEVPercent) external onlyGov { - require(_atlasOEVPercent + bundlerOEVPercent <= 100, "Invalid OEV percent"); - atlasOEVPercent = _atlasOEVPercent; + function setOevShareFastlane(uint256 oevShareFastlane_) external onlyGov { + if (oevShareFastlane_ + oevShareBundler > OEV_SHARE_SCALE) revert InvalidOevShare(); + oevShareFastlane = oevShareFastlane_; } - function setAtlasVault(address _atlasVault) external onlyGov { - atlasVault = _atlasVault; + function setOevAllocationDestination(address oevAllocationDestination_) external onlyGov { + if (oevAllocationDestination_ == address(0)) revert InvalidOevAllocationDestination(); + oevAllocationDestination = oevAllocationDestination_; } - function setOracleVault(address oracle, address _oracleVault) external onlyGov { - oracleVaults[oracle] = _oracleVault; + // ---------------------------------------------------- // + // Bundler Related Functions // + // ---------------------------------------------------- // + + function verifyBundlerWhitelist() external view { + // Whitelisting is enforced only if the whitelist is not empty + if (whitelistedBundlersCount > 0 && !bundlerWhitelist[_bundler()]) revert OnlyWhitelistedBundlerAllowed(); } function addBundlerToWhitelist(address bundler) external onlyGov { if (!bundlerWhitelist[bundler]) { bundlerWhitelist[bundler] = true; - NUM_WHITELISTED_BUNDLERS++; + whitelistedBundlersCount++; } } function removeBundlerFromWhitelist(address bundler) external onlyGov { if (bundlerWhitelist[bundler]) { bundlerWhitelist[bundler] = false; - NUM_WHITELISTED_BUNDLERS--; + whitelistedBundlersCount--; } } - function _onlyGov() internal view { - if (msg.sender != governance) revert OnlyGovernance(); + // ---------------------------------------------------- // + // Oracle Related Functions // + // ---------------------------------------------------- // + + function verifyOracleWhitelist(address oracle) external view { + // Whitelisting is enforced only if the whitelist is not empty + if (whitelistedOraclesCount > 0 && !oracleWhitelist[oracle]) revert OnlyWhitelistedOracleAllowed(); } - modifier onlyGov() { - _onlyGov(); - _; + function addOracleToWhitelist(address oracle) external onlyGov { + if (!oracleWhitelist[oracle]) { + oracleWhitelist[oracle] = true; + whitelistedOraclesCount++; + } } - function verifyBundlerWhitelist() external view { - if (NUM_WHITELISTED_BUNDLERS > 0 && !bundlerWhitelist[_bundler()]) revert OnlyWhitelistedBundlerAllowed(); + function removeOracleFromWhitelist(address oracle) external onlyGov { + if (oracleWhitelist[oracle]) { + oracleWhitelist[oracle] = false; + whitelistedOraclesCount--; + } } // ---------------------------------------------------- // // Atlas Hook Overrides // // ---------------------------------------------------- // - function _allocateValueCall(address, uint256 bidAmount, bytes calldata returnData) internal virtual override { - if (bidAmount == 0) return; + /** + * @notice Checks if the bundler is whitelisted and if the user is calling the update function + * @param userOp The user operation to check + * @return An empty bytes array + * @dev This function is delegatcalled + */ + function _preOpsCall(UserOperation calldata userOp) internal view override returns (bytes memory) { + // The bundler must be whitelisted + RedstoneOevDappControl(_control()).verifyBundlerWhitelist(); - address oracle = abi.decode(returnData, (address)); + // The user must be calling the present contract + if (userOp.dapp != _control()) revert InvalidUserDestination(); - uint256 oevPercentBundler = RedstoneOevDappControl(_control()).bundlerOEVPercent(); - uint256 oevPercentAtlas = RedstoneOevDappControl(_control()).atlasOEVPercent(); - address vaultAtlas = RedstoneOevDappControl(_control()).atlasVault(); - address vaultOracle = RedstoneOevDappControl(_control()).oracleVaults(oracle); + // The user must be calling the update function + if (bytes4(userOp.data) != bytes4(RedstoneOevDappControl.update.selector)) { + revert InvalidUserEntryCall(); + } - uint256 bundlerOev = (bidAmount * oevPercentBundler) / 100; - uint256 atlasOev = (bidAmount * oevPercentAtlas) / 100; - uint256 oracleOev = bidAmount - bundlerOev - atlasOev; + (address _oracle, bytes memory _updateCallData) = abi.decode(userOp.data[4:], (address, bytes)); - if (oracleOev > 0) SafeTransferLib.safeTransferETH(vaultOracle, oracleOev); - if (atlasOev > 0) SafeTransferLib.safeTransferETH(vaultAtlas, atlasOev); - if (bundlerOev > 0) SafeTransferLib.safeTransferETH(_bundler(), bundlerOev); + // The called oracle must be whitelisted + RedstoneOevDappControl(_control()).verifyOracleWhitelist(_oracle); + + // The update call data must be a valid updateDataFeedsValues call + if (bytes4(_updateCallData) != bytes4(IRedstoneAdapter.updateDataFeedsValues.selector)) { + revert InvalidUserUpdateCall(); + } + + return ""; + } + + /** + * @notice Allocates the bid amount to the relevant parties + * @param bidAmount The bid amount to be allocated + * @dev This function is delegatcalled + */ + function _allocateValueCall(address, uint256 bidAmount, bytes calldata) internal virtual override { + if (bidAmount == 0) return; + + // Get the OEV share for the bundler and transfer it + uint256 _oevShareBundler = bidAmount * RedstoneOevDappControl(_control()).oevShareBundler() / OEV_SHARE_SCALE; + if (_oevShareBundler > 0) SafeTransferLib.safeTransferETH(_bundler(), _oevShareBundler); + + // Get the OEV share for Fastlane and transfer it + uint256 _oevShareFastlane = bidAmount * RedstoneOevDappControl(_control()).oevShareFastlane() / OEV_SHARE_SCALE; + if (_oevShareFastlane > 0) SafeTransferLib.safeTransferETH(oevAllocationDestination, _oevShareFastlane); + + // Transfer the rest + uint256 _oevShareDestination = bidAmount - _oevShareBundler - _oevShareFastlane; + if (_oevShareDestination > 0) { + SafeTransferLib.safeTransferETH( + RedstoneOevDappControl(_control()).oevAllocationDestination(), _oevShareDestination + ); + } } // ---------------------------------------------------- // - // UserOp function // + // UserOp Function // // ---------------------------------------------------- // + /** + * @notice Updates the oracle with the new values + * @param oracle The oracle to update + * @param callData The call data to update the oracle with + * @return An empty bytes array + */ function update(address oracle, bytes calldata callData) external returns (bytes memory) { - RedstoneOevDappControl(_control()).verifyBundlerWhitelist(); + // Parameters have already been validated in _preOpsCall (bool success,) = oracle.call(callData); if (!success) revert OracleUpdateFailed(); - return abi.encode(oracle); + + return ""; } - // NOTE: Functions below are not delegatecalled // ---------------------------------------------------- // // View Functions // // ---------------------------------------------------- // diff --git a/src/contracts/examples/v2-example/V2DAppControl.sol b/src/contracts/examples/v2-example/V2DAppControl.sol index 95c897656..9eef3516a 100644 --- a/src/contracts/examples/v2-example/V2DAppControl.sol +++ b/src/contracts/examples/v2-example/V2DAppControl.sol @@ -51,9 +51,7 @@ contract V2DAppControl is DAppControl { event GiftedGovernanceToken(address indexed user, address indexed token, uint256 amount); - constructor( - address _atlas - ) + constructor(address _atlas) DAppControl( _atlas, msg.sender, diff --git a/src/contracts/helpers/Simulator.sol b/src/contracts/helpers/Simulator.sol index a9bbdd8d9..8d76bd618 100644 --- a/src/contracts/helpers/Simulator.sol +++ b/src/contracts/helpers/Simulator.sol @@ -37,9 +37,7 @@ contract Simulator is AtlasErrors { atlas = _atlas; } - function simUserOperation( - UserOperation calldata userOp - ) + function simUserOperation(UserOperation calldata userOp) external payable returns (bool success, Result simResult, uint256) diff --git a/src/contracts/interfaces/IAtlas.sol b/src/contracts/interfaces/IAtlas.sol index 762203e34..9bf1238b4 100644 --- a/src/contracts/interfaces/IAtlas.sol +++ b/src/contracts/interfaces/IAtlas.sol @@ -75,9 +75,7 @@ interface IAtlas { function solverLockData() external view returns (address currentSolver, bool calledBack, bool fulfilled); function totalSupply() external view returns (uint256); function bondedTotalSupply() external view returns (uint256); - function accessData( - address account - ) + function accessData(address account) external view returns (