Skip to content

Commit

Permalink
feat(resolver): updating docs, fix failing tests, add natspec
Browse files Browse the repository at this point in the history
  • Loading branch information
nutrina committed Nov 23, 2023
1 parent eecc1c1 commit 8566640
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 15 deletions.
11 changes: 10 additions & 1 deletion contracts/GitcoinResolver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,10 @@ contract GitcoinResolver is
}

/**
* @dev Returns the cached score for a given address.
*
* @param user The ETH address of the recipient
* @return The `CachedScore` for the given ETH address.
* A non-zero value in the `issuanceDate` indicates that a valid score has been retreived.
*/
function getCachedScore(
address user
Expand Down Expand Up @@ -242,6 +245,12 @@ contract GitcoinResolver is
return true;
}

/**
*
* @param user The ETH address of the recipient
* @param schema THE UID of the chema
* @return The attestation UID or 0x0 if not found
*/
function getUserAttestation(
address user,
bytes32 schema
Expand Down
15 changes: 14 additions & 1 deletion contracts/IGitcoinResolver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,27 @@ interface IGitcoinResolver {
uint32 score; // compacted uint value 4 decimal places
uint64 issuanceDate; // For checking the age of the stamp, without loading the attestation
uint64 expirationDate; // This makes sense because we want to make sure the stamp is not expired, and also do not want to load the attestation
uint32 scorerId; // would we need this ???
uint32 scorerId; // would we need this ??? TODO: to be clarified
}

/**
*
* @param user The ETH address of the recipient
* @param schema THE UID of the chema
* @return The attestation UID or 0x0 if not found
*/
function getUserAttestation(
address user,
bytes32 schema
) external view returns (bytes32);

/**
*
* @param user The ETH address of the recipient
* @return The `CachedScore` for the given ETH address.
* A non-zero value in the `issuanceDate` indicates that a valid score has been retreived.
*/

function getCachedScore(
address user
) external view returns (CachedScore memory);
Expand Down
60 changes: 51 additions & 9 deletions docs/00-onchain-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ OpenZeppelin's `Ownable`.
All of the smart contracts are upgradeable and pauseable.

The flow:

```mermaid
sequenceDiagram
actor User
Expand All @@ -67,13 +68,13 @@ sequenceDiagram
Attester->>EAS : multiAttest
activate Resolver
EAS->>Resolver : multiAttest
Resolver-->>EAS :
Resolver-->>EAS :
deactivate Resolver
EAS-->>Attester : UUIDs: bytes32[]
deactivate EAS
Attester-->>Verifier :
Attester-->>Verifier :
deactivate Attester
Verifier-->>App :
Verifier-->>App :
deactivate Verifier
App-->>User : display onchain status
Expand All @@ -96,7 +97,6 @@ sequenceDiagram
deactivate Decoder
```


## GitcoinAttester

Here are the main features:
Expand Down Expand Up @@ -161,13 +161,19 @@ recipient, in order for the call to `verifyAndAttest` to get through. It will be
reverted otherwise.

## GitcoinResolver
You can find the implementation of the GitcoinResolver _[here](../contracts/GitcoinResolver.sol)_

EAS provides a mechanism to perform additional validations for stamps and
implement additional smart contract functionality related to attestations using
[resolver contracts](https://docs.attest.sh/docs/tutorials/resolver-contracts).
For our use-case we will use resolver contracts to track which attestations a
given recipient owns (this information is not provided by the EAS smart contract
by default).
For our use-case we will use resolver contracts for the following purposes:

- to track which attestations a given recipient owns (this information is not
provided by the EAS smart contract by default)
- caching the latest score that a user has, in order to provide more efficient
access to a users score (cheaper in terms of gas costs)

### Tracking attestations

The attestations are stored in a mapping that allows storing attestations
from any schema:
Expand All @@ -176,16 +182,52 @@ from any schema:
mapping(address => mapping(bytes32 => bytes32)) public userAttestations;
```

The meaning of this nested mapping is the following:

```txt
user ETH address => schema UID => attestation UID
```

In order to ensure the integrity of the data that a resolver stores, resolver
smart contract shall only validate and store date from trusted sources:
smart contract shall only validate and store data from trusted sources:

- a trusted EAS contract
- a trusted Attester

### Caching users scores

In order to provide faster access to a users score, the informatio from score
attestations is cached in an attribute of the `GitcoinResolver` smart contract:

```sol
// Mapping of addresses to scores
mapping(address => CachedScore) private scores;
```

where `CachedScore` is defined as follows:

```sol
struct CachedScore {
uint32 score;
uint64 issuanceDate;
uint64 expirationDate;
uint32 scorerId;
}
```

Retreiving the latest score for a user becomes much cheaper in terms of gas costs
and easier using the helper function:

```sol
function getCachedScore(
address user
) external view returns (CachedScore memory);
```

## GitcoinPassportDecoder

This is a convenience smart contract that can be used by any party to check for the on-chain passport attestation for a given ETH address.
This is a convenience smart contract that can be used by any party to check for
the on-chain passport attestation for a given ETH address.
See the documentation [How to Decode Passport Attestations
](./05-querying-passport-attestations-onchain.md) for more details.

Expand Down
6 changes: 3 additions & 3 deletions test/GitcoinResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ describe("GitcoinResolver", function () {
.attest(attestation);
const attestReceipt = attestRequest.wait();

const score = await gitcoinResolver.scores(recipient.address);
const score = await gitcoinResolver.getCachedScore(recipient.address);

// Score should have been casted to a 4 digit value
expect(score[0]).to.equal("123456");
Expand Down Expand Up @@ -223,7 +223,7 @@ describe("GitcoinResolver", function () {
.attest(attestation);
const attestReceipt = attestRequest.wait();

const score = await gitcoinResolver.scores(recipient.address);
const score = await gitcoinResolver.getCachedScore(recipient.address);

// Score should have been casted to a 4 digit value
expect(score[0]).to.equal("123400");
Expand Down Expand Up @@ -253,7 +253,7 @@ describe("GitcoinResolver", function () {
.attest(attestation);
const attestReceipt = attestRequest.wait();

const score = await gitcoinResolver.scores(recipient.address);
const score = await gitcoinResolver.getCachedScore(recipient.address);

// Score should have been casted to a 4 digit value
expect(score[0]).to.equal("123456");
Expand Down
2 changes: 1 addition & 1 deletion test/Upgrades.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ describe("Upgrading GitcoinAttester", function () {
});
});

describe.only("Upgrading GitcoinResolver", function () {
describe("Upgrading GitcoinResolver", function () {
this.beforeEach(async function () {
const [owner, mockEASAccount] = await ethers.getSigners();
this.owner = owner;
Expand Down

0 comments on commit 8566640

Please sign in to comment.