Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: fix trusted attester linked list clearing #75

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/core/TrustManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@ abstract contract TrustManager is IRegistry {

mapping(address account => TrustedAttesterRecord attesters) internal $accountToAttester;

function _requireEmptyList(TrustedAttesterRecord storage $trustedAttester) internal view {
address _tmp = $trustedAttester.attester;

// if the first entry is zero, the trusted list was not previously initialized, and can thus be safely set.
if (_tmp == ZERO_ADDRESS) return;

// otherwise, loop over the linked list to check if it is empty
// find the last entry in the linked list.
for (uint256 i; i <= type(uint8).max; i++) {
_tmp = $trustedAttester.linkedAttesters[_tmp][msg.sender];
if (_tmp == ZERO_ADDRESS) return;
}
}

/**
* @inheritdoc IERC7484
*/
Expand All @@ -49,6 +63,9 @@ abstract contract TrustManager is IRegistry {
revert InvalidThreshold();
}

// ensure that the trusted attester list is cleared before re-initializing it.
_requireEmptyList($trustedAttester);

$trustedAttester.attesterCount = uint8(attestersLength);
$trustedAttester.threshold = threshold;
$trustedAttester.attester = attesters[0];
Expand Down
46 changes: 46 additions & 0 deletions test/TrustedAttesterList.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "./Attestation.t.sol";
import "src/DataTypes.sol";
import { LibSort } from "solady/utils/LibSort.sol";

contract POCTest is AttestationTest {
using LibSort for address[];

function setUp() public override {
super.setUp();
}

function testPOC() external prankWithAccount(smartAccount1) {
uint8 threshold = 1;
address[] memory trustedAttesters = new address[](3);
trustedAttesters[0] = address(attester1.addr);
trustedAttesters[1] = address(attester2.addr);
trustedAttesters[2] = makeAddr("attester3");

trustedAttesters.sort();
trustedAttesters.uniquifySorted();

registry.trustAttesters(threshold, trustedAttesters);

address[] memory result = registry.findTrustedAttesters(smartAccount1.addr);

assertEq(result.length, trustedAttesters.length);
for (uint256 i; i < trustedAttesters.length; i++) {
assertEq(result[i], trustedAttesters[i]);
}

_make_WhenUsingValidECDSA(attester2);
registry.check(address(module1), ModuleType.wrap(1));

address[] memory newTrustedAttesters = new address[](1);
newTrustedAttesters[0] = address(attester1.addr);
registry.trustAttesters(1, newTrustedAttesters);
address[] memory newResult = registry.findTrustedAttesters(smartAccount1.addr);
assertEq(newResult.length, 1);
assertEq(newResult[0], address(attester1.addr));

registry.check(address(module1), ModuleType.wrap(1));
}
}
Loading