UtilityChecker
UtilityChecker is a read-only helper that tells, before a transfer is signed, whether it would pass and which check would refuse it. Every function takes the address of a token, so one deployment answers for every asset of a network. How to use it in an application is in Pre-flight checks with UtilityChecker.
At a glance
Source
contracts/utils/UtilityChecker.sol, contracts/utils/UtilityCheckerProxy.sol
Interface
IUtilityChecker
Deployed as
One implementation behind a UtilityCheckerProxy (ERC-1967, UUPS), by scripts/DeployUtilityChecker.s.sol
Access
Every function is a view open to anyone. upgradeToAndCall is reserved to the owner of the proxy
State
Its owner and its implementation. Nothing about any token, and no role in any access manager
Trust statement.
UtilityCheckerdecides nothing: the token makes every check again when a transfer executes. Its owner can replace its code, so a wrong answer can mislead a display. It cannot move or block a token.
Functions
getTransferStatus(_token, _from, _to, _amount)
_freezeStatus: the token is not paused and getFreezeStatus reports no freeze. _eligibilityStatus: TREXRegistry.isVerified(_to). _complianceStatus: every entry of getTransferDetails passes
getFreezeStatus(_token, _from, _to, _amount)
_frozen: true when either address is frozen, or when the amount exceeds the available balance. _availableBalance: 0 when either address is frozen, the free balance of _from otherwise
getVerifiedDetails(_token, _userAddress)
_details: one entry per required claim topic. _walletStatus: the status of the address in the IdentityFactory: None, Active or Revoked
getTransferDetails(_token, _from, _to, _value)
_details: one entry per RULE module bound to the compliance of the token
The two structs
EligibilityCheckDetails
issuer
The Claim Issuer whose claim was read for the topic. Zero when no trusted issuer made a claim
topic
The claim topic. 0 when no claim was found: take the topic from the list of required topics, at the same index
pass
The answer of isClaimValid on the issuer, or false when that call reverts
ComplianceCheckDetails
moduleName
IModule.name() of the module
allowedAmount
IModule.allowedAmount(ctx) for this movement
pass
Whether the value is at most allowedAmount
Behaviors to know
A transfer of zero
Not detected: the token reverts with ZeroValue
transferFrom
The allowance and the spender policy are not read
An address that resolves to no identity
getVerifiedDetails reverts as soon as one required topic has a trusted issuer. Read TREXRegistry.identity(address) first
Several trusted issuers for one topic
isVerified accepts any valid claim. The entry of getVerifiedDetails describes the last issuer of the list
A revoked wallet
The entries can all pass while isVerified is false: read _walletStatus
Eligibility checks disabled on the registry
_eligibilityStatus is true for every address
A sender with no identity while a RULE module is bound
ModularCompliance.canTransfer refuses. getTransferDetails still asks the modules and can report a pass
Positions on satellites
Not read. The functions describe a movement on the reference chain
A rule that is not monotonic
Its allowedAmount is the maximum or 0 for the amount asked, and says nothing about other amounts
The direct views give the decision without the detail: Token.paused(), Token.isFrozen(address), Token.freeBalanceOf(address), TREXRegistry.isVerified(address), ModularCompliance.canTransfer(from, to, amount).
Last updated