Skip to content

Commit

Permalink
Update ERC-6956: Move to Review
Browse files Browse the repository at this point in the history
Merged by EIP-Bot.
  • Loading branch information
tbergmueller authored and RaphaelHardFork committed Jan 30, 2024
1 parent d1478f0 commit 06f1763
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 82 deletions.
83 changes: 17 additions & 66 deletions ERCS/erc-6956.md

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions assets/erc-6956/contracts/ERC6956.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import "@openzeppelin/contracts/utils/Strings.sol";

import "./IERC6956.sol";

/** Used for several authorization mechansims, e.g. who can burn, who can set approval, ...
/** Used for several authorization mechanisms, e.g. who can burn, who can set approval, ...
* @dev Specifying the role in the ecosystem. Used in conjunction with IERC6956.Authorization
*/
enum Role {
Expand Down Expand Up @@ -163,7 +163,7 @@ contract ERC6956 is
}

/**
* @dev A very simple function wich MUST return false, when `a` is not a maintainer
* @dev A very simple function which MUST return false, when `a` is not a maintainer
* When derived contracts extend ERC6956 contract, this function may be overridden
* e.g. by using AccessControl, onlyOwner or other common mechanisms
*
Expand Down Expand Up @@ -265,15 +265,15 @@ contract ERC6956 is
/// @param to Beneficiary account address
/// @param anchor The anchor (from Merkle tree)
function _safeMint(address to, bytes32 anchor) internal virtual {
assert(tokenByAnchor[anchor] <= 0); // saftey for contract-internal errors
assert(tokenByAnchor[anchor] <= 0); // safety for contract-internal errors
uint256 tokenId = _burnedTokensByAnchor[anchor];

if(tokenId < 1) {
_tokenIdCounter.increment();
tokenId = _tokenIdCounter.current();
}

assert(anchorByToken[tokenId] <= 0); // saftey for contract-internal errors
assert(anchorByToken[tokenId] <= 0); // safety for contract-internal errors
anchorByToken[tokenId] = anchor;
tokenByAnchor[anchor] = tokenId;
super._safeMint(to, tokenId);
Expand Down Expand Up @@ -429,7 +429,7 @@ contract ERC6956 is
// Indicates general float-ability, i.e. whether anchors can be digitally dropped and released

// OWNER and ASSET shall normally be in sync anyway, so this is reasonable default
// authorization for approve and burn, as it mimicks ERC-721 behavior
// authorization for approve and burn, as it mimics ERC-721 behavior
burnAuthorization = Authorization.OWNER_AND_ASSET;
approveAuthorization = Authorization.OWNER_AND_ASSET;
}
Expand Down
6 changes: 3 additions & 3 deletions assets/erc-6956/contracts/IERC6956.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ interface IERC6956 {
* @dev This emits when approveAnchor() is called and corresponds to ERC-721 behavior
* @param owner The owner of the anchored tokenId
* @param approved The approved address, address(0) indicates there is no approved address
* @param anchor The anchor, for which approval has been chagned
* @param anchor The anchor, for which approval has been changed
* @param tokenId ID (>0) of the anchored token
*/
event AnchorApproval(address indexed owner, address approved, bytes32 indexed anchor, uint256 tokenId);
Expand All @@ -47,15 +47,15 @@ interface IERC6956 {
/**
* @notice This emits when an attestation has been used indicating no second attestation with the same attestationHash will be accepted
* @param to The to address specified in the attestation
* @param anchor The anchor specificed in the attestation
* @param anchor The anchor specified in the attestation
* @param attestationHash The hash of the attestation, see ERC-6956 for details
* @param totalUsedAttestationsForAnchor The total number of attestations already used for the particular anchor
*/
event AttestationUse(address indexed to, bytes32 indexed anchor, bytes32 indexed attestationHash, uint256 totalUsedAttestationsForAnchor);

/**
* @notice This emits when the trust-status of an oracle changes.
* @dev Trusted oracles must explicitely be specified.
* @dev Trusted oracles must explicitly be specified.
* If the last event for a particular oracle-address indicates it's trusted, attestations from this oracle are valid.
* @param oracle Address of the oracle signing attestations
* @param trusted indicating whether this address is trusted (true). Use (false) to no longer trust from an oracle.
Expand Down
4 changes: 2 additions & 2 deletions assets/erc-6956/contracts/IERC6956AttestationLimited.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ interface IERC6956AttestationLimited is IERC6956 {

/// @notice Returns number of attestations left for a particular anchor
/// @dev Is computed by comparing the attestationsUsedByAnchor(anchor) and the current attestation limit
/// (current limited emitted via GlobalAttestationLimitUpdate or AttestationLimt events)
/// (current limited emitted via GlobalAttestationLimitUpdate or AttestationLimit events)
function attestationUsagesLeft(bytes32 anchor) external view returns (uint256 nrTransfersLeft);

/// @notice Indicates the policy, in which direction attestation limits can be updated (globally or per anchor)
function attestationLimitPolicy() external view returns (AttestationLimitPolicy policy);

/// @notice This emits when the global attestation limt is updated
/// @notice This emits when the global attestation limit is updated
event GlobalAttestationLimitUpdate(uint256 indexed transferLimit, address updatedBy);

/// @notice This emits when an anchor-specific attestation limit is updated
Expand Down
25 changes: 25 additions & 0 deletions assets/erc-6956/minimalAttestationSample.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export async function minimalAttestationSample() {
// #################################### ACCOUNTS
// Alice shall get the NFT, oracle signs the attestation off-chain
// Oracle needs to be a trusted Oracle of the smart-contract that shall accept the generated attestation
const [alice, oracle] = await ethers.getSigners();

// #################################### CREATE AN ATTESTATION
const to = alice.address;
const anchor = '0x4cc52563699fb1e3333b8aab3ecf016f8fd084e6fc48edf8603d83d4c5b97536'

const attestationTime = Math.floor(Date.now() / 1000.0); // Now in seconds UTC
const validStartTime = 0;
const validEndTime = attestationTime + 15 * 60; // 15 minutes valid from attestation

const messageHash = ethers.utils.solidityKeccak256(
["address", "bytes32", "uint256", 'uint256', "uint256"],
[to, anchor, attestationTime, validStartTime, validEndTime]
);
const sig = await signer.signMessage(ethers.utils.arrayify(messageHash));

return ethers.utils.defaultAbiCoder.encode(
['address', 'bytes32', 'uint256', 'uint256', 'uint256', 'bytes'],
[to, anchor, attestationTime, validStartTime, validEndTime, sig]
);
}
4 changes: 2 additions & 2 deletions assets/erc-6956/test/ERC6956.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export async function minimalAttestationExample() {
}

describe("ERC6956: Asset-Bound NFT --- Basics", function () {
// Fixture to deploy the abnftContract contract and assigne roles.
// Fixture to deploy the abnftContract contract and assign roles.
// Besides owner there's user, minter and burner with appropriate roles.
async function deployAbNftFixture() {
// Contracts are deployed using the first signer/account by default
Expand Down Expand Up @@ -175,7 +175,7 @@ describe("Authorization Map tests", function () {
.to.emit(abnftContract, "AnchorTransfer")
.withArgs(alice.address, bob.address, anchor, 1);

// Token is now at bob... so alice may hire a hacker quickly and re-use her attestation to get
// Token is now at bob... so alice may hire a hacker quickly and reuse her attestation to get
// the token back from Bob ... which shall of course not work
await expect(abnftContract.connect(hacker)["transferAnchor(bytes)"](mintAttestationAlice))
.to.revertedWith("ERC6956-E9") // Standard ERC721 event
Expand Down
8 changes: 4 additions & 4 deletions assets/erc-6956/test/ERC6956Full.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export enum FloatState {
}

describe("ERC6956: Asset-Bound NFT --- Full", function () {
// Fixture to deploy the abnftContract contract and assigne roles.
// Fixture to deploy the abnftContract contract and assign roles.
// Besides owner there's user, minter and burner with appropriate roles.
async function deployAbNftFixture() {
// Contracts are deployed using the first signer/account by default
Expand Down Expand Up @@ -120,12 +120,12 @@ describe("Anchor-Floating", function () {
expect(await abnftContract.floating(anchor))
.to.be.equal(false); // one was used to mint

// Now alice, as the owner decides to make it explicitely floatable
// Now alice, as the owner decides to make it explicitly floatable
expect(await abnftContract.connect(alice).float(anchor, FloatState.Floating))
.to.emit(abnftContract, "FloatingStateChange")
.withArgs(anchor, 1, FloatState.Floating, alice.address)

// It is now explicitely floatable
// It is now explicitly floatable
expect(await abnftContract.floating(anchor))
.to.be.equal(true); // one was used to mint

Expand Down Expand Up @@ -211,7 +211,7 @@ describe("Anchor-Floating", function () {
.withArgs(alice.address,bob.address, tokenId);
});

it("SHOULDN'T allow owner to transfer token when explicitely marked anchored", async function () {
it("SHOULDN'T allow owner to transfer token when explicitly marked anchored", async function () {
const { abnftContract, anchor, maintainer, alice, bob, mallory } = await loadFixture(deployAbNftAndMintTokenToAliceFixture);
const tokenId = await abnftContract.tokenByAnchor(anchor);

Expand Down

0 comments on commit 06f1763

Please sign in to comment.