Dria

Swan
NFTHardhat
21,000 USDC
View results
Submission Details
Severity: medium
Valid

Nothing At Stake

Summary

The staking mechanism used to ensure the integrity of the validator and generator roles is economically insecure.

Vulnerability Details

To become a validator or a generator, permissionless actors must stake sufficient tokens for the role:

/// @notice Register an Oracle.
/// @dev Reverts if the user is already registered or has insufficient funds.
/// @param kind The kind of Oracle to unregister.
function register(LLMOracleKind kind) public {
@> uint256 amount = getStakeAmount(kind); /// @audit ensure minimum stake for role
// ensure the user is not already registered
if (isRegistered(msg.sender, kind)) {
revert AlreadyRegistered(msg.sender);
}
// ensure the user has enough allowance to stake
if (token.allowance(msg.sender, address(this)) < amount) {
revert InsufficientFunds();
}
token.transferFrom(msg.sender, address(this), amount);
// register the user
registrations[msg.sender][kind] = amount;
emit Registered(msg.sender, kind);
}

https://github.com/Cyfrin/2024-10-swan-dria/blob/c8686b199daadcef3161980022e12b66a5304f8e/contracts/llm/LLMOracleRegistry.sol#L91C5-L111C6

Likewise, registered generators and validators may unstake via a call to unregister:

/// @notice Remove registration of an Oracle.
/// @dev Reverts if the user is not registered.
/// @param kind The kind of Oracle to unregister.
/// @return amount Amount of stake approved back.
function unregister(LLMOracleKind kind) public returns (uint256 amount) {
amount = registrations[msg.sender][kind];
// ensure the user is registered
if (amount == 0) {
revert NotRegistered(msg.sender);
}
// unregister the user
delete registrations[msg.sender][kind];
emit Unregistered(msg.sender, kind);
// approve its stake back
token.approve(msg.sender, token.allowance(address(this), msg.sender) + amount);
}

https://github.com/Cyfrin/2024-10-swan-dria/blob/c8686b199daadcef3161980022e12b66a5304f8e/contracts/llm/LLMOracleRegistry.sol#L117C1-L131C6

First, notice that there is no implicit time or economic cost of staking, stakers may atomically call register and unregister.

i.e. it is possible for an actor to register and unregister repeatedly

Therefore, regardless of how great the minimum stake amount is for each role, it is possible to merely flash loan the necessary funds in order to participate in governance. Likewise, this also means an actor could reuse the same funds across multiple atomic registrations and unregistrations to vote across multiple accounts and skew consensus in their favour, i.e.

  1. Register

  2. Respond

  3. Unregister

  4. Repeat

By result, the current staking mechanism is ineffective.

Impact

When a validator or generator is staked, they earn governance rights backed by Proof-of-Work:

function respond(uint256 taskId, uint256 nonce, bytes calldata output, bytes calldata metadata)
public
@> onlyRegistered(LLMOracleKind.Generator) /// @audit must have registered
onlyAtStatus(taskId, TaskStatus.PendingGeneration)
{
TaskRequest storage task = requests[taskId];
// ensure responder to be unique for this task
for (uint256 i = 0; i < responses[taskId].length; i++) {
if (responses[taskId][i].responder == msg.sender) {
revert AlreadyResponded(taskId, msg.sender);
}
}
// check nonce (proof-of-work)
@> assertValidNonce(taskId, task, nonce); /// @audit supply valid proof of work for response

https://github.com/Cyfrin/2024-10-swan-dria/blob/c8686b199daadcef3161980022e12b66a5304f8e/contracts/llm/LLMOracleCoordinator.sol#L207C5-L222C47

The security of Proof-of-Work consensus is fundamentally derived from the costs of producing valid work.

Through the use of either flash loans or by merely reusing the stake between different accounts, an actor can reduce their operating costs to outperform competitors by diverting economic resources into Proof of Work, placing competitors at a disadvantage. Additionally, this allows subversive stakers to possess the same amount of influence as protocol-aligned actors who by contrast make a significant economic sacrifice.

By reusing (or flash loaning) stake, the malicious actor is capable of submitting as much Proof of Work as honest governance participants who suffer the economic burden of staking.

Once this flaw in the incentive mechanism is common knowledge, governance participants must use the same sybil strategy in order to remain competitive - rendering the staking mechanism ineffective.

Tools Used

Manual Review

Recommendations

To ensure sticky stake liquidity, enforce a minimum stake duration.

Updates

Lead Judging Commences

inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Validated
Assigned finding tags:

There is no oracle whitelisting

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.