Skip to content

Commit

Permalink
updated natspec and readme (#43)
Browse files Browse the repository at this point in the history
* updated natspec and readme

* Final cleanup

* author ordering

---------

Co-authored-by: Patrick Gallagher <[email protected]>
  • Loading branch information
MrDeadCe11 and pi0neerpat authored Jun 25, 2024
1 parent a961ce0 commit c4900dc
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 30 deletions.
39 changes: 25 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@
</a>
</p>

# Dynamic Traits Enforcement Zone
# Dynamic Traits Enforcement Zone

A Seaport zone for specifying and enforcing values of ERC-7496 Dynamic Traits
A Seaport zone which implements [ERC-7496](https://eips.ethereum.org/EIPS/eip-7496) to enforce NFT trait details.

View the SIP-15 standard: https://github.com/open-dollar/SIPs/blob/main/SIPS/sip-15.md
The zone was developed to align with the [SIP-15](https://github.com/open-dollar/SIPs/blob/main/SIPS/sip-15.md) standard from Seaport.

## Setup

1. Copy the `.env.example` and update the following values:
Use the command-line scripts to create, submit, and fulfill an order for an Open Dollar NFV, using the OpenSea API.

1. Copy the `.env.example` and update the following values:

```bash
ARB_SEPOLIA_RPC=
Expand All @@ -28,26 +30,35 @@ ARB_SEPOLIA_OFFERER_PK=
ARB_SEPOLIA_BUYER_PK=
```

2. Use the “Offerer” wallet to open a vault on Open Dollar testnet https://app.dev.opendollar.com
2. Use the “Offerer” wallet to open a vault on Open Dollar testnet https://app.dev.opendollar.com

2. User the “Buyer” wallet to mint the consideration token "ARB" at https://sepolia.arbiscan.io/address/0x3018EC2AD556f28d2c0665d10b55ebfa469fD749#writeContract
3. User the “Buyer” wallet to mint the consideration token "ARB" at https://sepolia.arbiscan.io/address/0x3018EC2AD556f28d2c0665d10b55ebfa469fD749#writeContract

## Create Listing

## Create listing
Use the `create-listing` scrip to create an order from the "Offerer" wallet.

```bash
yarn
# Install and build the contracts
yarn
yarn build

# Create Listing
yarn create-listing <chainName> <tokenId> <considerationAmountInEther>
yarn create-listing sepolia 313 0.000001
# eg.
yarn create-listing sepolia 313 0.000001
```

## Fulfill Order

# Execute listing
Use the fulfill script to execute the order from the "Buyer" wallet.

```bash
yarn fulfill <chainName> <orderPath>
# eg.
yarn fulfill sepolia orders/order-1-1718667016.json
```

Notes:
- Vaults have a 100 second cooldown on testnet before they can be transferred.
- Order `endTime` is 24 hours
Important Notes:

- On testnet, Open Dollar NFVs have a 100 second cooldown after any modification before they can be transferred.
- The default order `endTime` is currently 24 hours.
18 changes: 13 additions & 5 deletions src/contracts/SIP15Zone.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import {SIP15ZoneEventsAndErrors} from '../interfaces/SIP15ZoneEventsAndErrors.s
import {ISIP15Zone} from '../interfaces/ISIP15Zone.sol';

/**
* @title ODSeaportZone
* @author MrDeadce11 & stephankmin
* @notice SIP15Zone is an implementation of SIP-15. It verifies that the dynamic traits of an NFT
* have not changed between the time of order creation and the time of order fulfillment.
* @title DynamicTraitsEnforcementZone
* @author MrDeadCe11, daopunk, pi0neerpat, CupOJoseph, stephankmin
* @notice DynamicTraitsEnforcementZone is an implementation of SIP-15 for enforcing ERC-7496 traits. It verifies the state of
* dynamic traits after a transfer and supports substandards 1 through 5. Substandard docs: https://github.com/open-dollar/SIPs/blob/main/SIPS/sip-15.md
*/
contract SIP15Zone is ERC165, ISIP15Zone, SIP15ZoneEventsAndErrors {
using SIP15Decoder for bytes;
Expand All @@ -25,7 +25,7 @@ contract SIP15Zone is ERC165, ISIP15Zone, SIP15ZoneEventsAndErrors {
constructor() {}

/**
* @dev Validates an order.
* @dev Validates an order. called after order is fulfilled and offers and considerations have been transfered
*
* @param zoneParameters The context about the order fulfillment and any
* supplied extraData.
Expand Down Expand Up @@ -55,13 +55,21 @@ contract SIP15Zone is ERC165, ISIP15Zone, SIP15ZoneEventsAndErrors {
return this.validateOrder.selector;
}

/**
* @dev called before order fulfillment. no authorization is required for this zone.
* @return authorizedOrderMagicValue the bytes4 magic order value that authorizes the order
*/
function authorizeOrder(ZoneParameters calldata /* zoneParameters*/ )
external
view
returns (bytes4 authorizedOrderMagicValue)

Check warning on line 65 in src/contracts/SIP15Zone.sol

View workflow job for this annotation

GitHub Actions / Run Linters (22.x)

'authorizedOrderMagicValue' should start with _
{
return this.authorizeOrder.selector;
}
/**
* @dev decodes extraData acording to the substandard and then checks the traits according to
* the designated comparison enum/enums. See SIP15encoder for encoding details.
*/

function _validateSubstandard(uint8 substandardVersion, bytes calldata extraData) internal view {

Check warning on line 74 in src/contracts/SIP15Zone.sol

View workflow job for this annotation

GitHub Actions / Run Linters (22.x)

'substandardVersion' should start with _

Check warning on line 74 in src/contracts/SIP15Zone.sol

View workflow job for this annotation

GitHub Actions / Run Linters (22.x)

'extraData' should start with _
address token;

Check warning on line 75 in src/contracts/SIP15Zone.sol

View workflow job for this annotation

GitHub Actions / Run Linters (22.x)

'token' should start with _
Expand Down
2 changes: 1 addition & 1 deletion src/contracts/Vault721Adapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {IERC7496} from 'shipyard-core/src/dynamic-traits/interfaces/IERC7496.sol
import {IERC721} from '@openzeppelin/token/ERC721/IERC721.sol';
/**
* @title Adds support for ERC7496 to an existing ERC721
* @author OpenFi Foundation
* @author daopunk, MrDeadCe11, pi0neerpat, CupOJoseph
* @notice IERC7496 events are never emitted since NFVState is tracked in Vault721
*/

Expand Down
35 changes: 33 additions & 2 deletions src/sips/SIP15Decoder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,43 @@ library SIP15Decoder {
/**
* @notice Read the SIP15 substandard version byte from the extraData field of a SIP15 encoded bytes array.
* @param extraData bytes calldata
* @return substandard the single byte substandard number 0-5
*/
function decodeSubstandardVersion(bytes calldata extraData) internal pure returns (bytes1 substandard) {
return BaseSIPDecoder.decodeSubstandardVersion(extraData);
}
/**
* @notice decodes data encoding with substandard1Efficient encoder
* @param extraData the encoded bytes with substandard and the extra data
* @return (uint8 comparisonEnum, address token, uint256 identifier, bytes32 traitValue, bytes32 traitKey)
*/

function decodeSubstandard1(bytes calldata extraData)
function decodeSubstandard1Efficient(bytes calldata extraData)
internal
pure
returns (uint8, address, uint256, bytes32, bytes32)
{
return _decodeSingleTraitsWithOffset(extraData, 1);
}

function decodeSubstandard1Efficient(bytes calldata extraData)
/**
* @notice decodes data encoding with substandard1 encoder
* @param extraData the encoded bytes with substandard and the extra data
* @return (uint8 comparisonEnum, address token, uint256 identifier, bytes32 traitValue, bytes32 traitKey)
*/
function decodeSubstandard1(bytes calldata extraData)
internal
pure
returns (uint8, address, uint256, bytes32, bytes32)
{
return _decodeSingleTraitsWithOffset(extraData, 1);
}

/**
* @notice decodes data encoding with substandard2 encoder
* @param extraData the encoded bytes with substandard and the extra data
* @return (uint8 comparisonEnum, address token, uint256 identifier, bytes32 traitValue, bytes32 traitKey)
*/
function decodeSubstandard2(bytes calldata extraData)
internal
pure
Expand All @@ -37,6 +53,11 @@ library SIP15Decoder {
return _decodeSingleTraitsWithOffset(extraData, 1);
}

/**
* @notice decodes data encoding with substandard3 encoder
* @param extraData the encoded bytes with substandard and the extra data
* @return (uint8 comparisonEnum, address token, uint256 identifier, bytes32 traitValue, bytes32 traitKey)
*/
function decodeSubstandard3(bytes calldata extraData)
internal
pure
Expand All @@ -45,6 +66,11 @@ library SIP15Decoder {
return _decodeSingleTraitsWithOffset(extraData, 1);
}

/**
* @notice decodes data encoding with substandard4 encoder
* @param extraData the encoded bytes with substandard and the extra data
* @return (uint8 comparisonEnum, address token, uint256[] identifiers, bytes32 traitValue, bytes32 traitKey)
*/
function decodeSubstandard4(bytes calldata extraData)
internal
pure
Expand All @@ -53,6 +79,11 @@ library SIP15Decoder {
return abi.decode(extraData[1:], (uint8, address, uint256[], bytes32, bytes32));
}

/**
* @notice decodes data encoding with substandard1 encoder
* @param extraData the encoded bytes with substandard and the extra data
* @return Substandard5Comparison
*/
function decodeSubstandard5(bytes calldata extraData) internal pure returns (Substandard5Comparison memory) {
return abi.decode(extraData[1:], (Substandard5Comparison));
}
Expand Down
24 changes: 20 additions & 4 deletions src/sips/SIP15Encoder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ library SIP15Encoder {
/**
* @notice Generate a zone hash for an SIP15 contract,
* @param encodedData the SIP15 encoded extra data
* @return bytes32 hashed encoded data
*/
function generateZoneHash(bytes memory encodedData) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(encodedData));
Expand All @@ -26,7 +27,9 @@ library SIP15Encoder {
/**
* @notice Encode extraData for SIP15-substandard-1 Efficient, which specifies the
* first consideration item, comparison "equal to", single trait key, zero trait value
* @param zoneParameters the orderParams of the order to be encoded
* @param traitKey the bytes32 encoded trait key for checking a trait on an ERC7496 token
* @return bytes the encoded extra data with added substandard
*/
function encodeSubstandard1Efficient(
ZoneParameters memory zoneParameters,
Expand All @@ -42,10 +45,12 @@ library SIP15Encoder {

/**
* @notice Encode extraData for SIP15-substandard-1, which specifies the
* first offer item, token address and id from first offer item
* token address and id from first offer item
* @param zoneParameters the zone parameters with the offer to be used for the token and identifier
* @param comparisonEnum the comparison enum 0 - 5
* @param traitKey the bytes32 encoded trait key for checking a trait on an ERC7496 token
* @param traitValue the expected value of the trait.
* @return bytes the encoded extra data with added substandard
*/
function encodeSubstandard1(
ZoneParameters memory zoneParameters,
Expand All @@ -63,11 +68,12 @@ library SIP15Encoder {

/**
* @notice Encode extraData for SIP15-substandard-2, which specifies
* the token and identifier from the first consideration item as well as a comparison enum, trait key and trait value
* @param zoneParameters memory zoneParameters,
* the token and identifier from the first consideration item as well as a comparison enum, trait key and expected trait value
* @param zoneParameters the zoneParameters of the order whose first consideration will be used for the token and identifier
* @param comparisonEnum The comparison enum 0 - 5
* @param traitValue The expecta value of the trait
* @param traitKey the bytes32 encoded trait key for checking a trait on an ERC7496 token
* @return bytes the encoded extra data with added substandard
*/
function encodeSubstandard2(
ZoneParameters memory zoneParameters,
Expand All @@ -91,6 +97,7 @@ library SIP15Encoder {
* @param identifier the tokenId of the token to be checked
* @param traitKey the bytes32 encoded trait key for checking a trait on an ERC7496 token
* @param traitValue the expected value of the trait.
* @return bytes the encoded extra data with added substandard
*/
function encodeSubstandard3(
uint8 comparisonEnum,
Expand All @@ -111,6 +118,7 @@ library SIP15Encoder {
* @param identifiers the tokenId of the token to be checked
* @param traitKey the bytes32 encoded trait key for checking a trait on an ERC7496 token
* @param traitValue the expected value of the trait.
* @return bytes the encoded extra data with added substandard
*/
function encodeSubstandard4(
uint8 comparisonEnum,
Expand All @@ -124,7 +132,15 @@ library SIP15Encoder {

/**
* @notice Encode extraData for SIP15-substandard-5, which specifies a single tokenIdentifier
* @param comparisonStruct the struct of comparison data
* @param comparisonStruct the struct of comparison data with the following values:
* - uint8[] comparisonEnums the array of comparison enums for each trait key and expected value, must be the same length as the trait keys and values.
* - address token the address of the token whose traits will be checked
* - address traits the address that contains the ERC7496 traits. this is useful if you have an erc712 with traits availible at a
* different address leave as address(0) if the traits can be retreived from the same address as the token
* - uint256 identifier the identifier of the token to be checked;
* - bytes32[] traitValues the array of expected trait values
* - bytes32[] traitKeys the encoded trait keys ;
* @return bytes the encoded extra data with added substandard
*/
function encodeSubstandard5(Substandard5Comparison memory comparisonStruct) internal pure returns (bytes memory) {
return abi.encodePacked(uint8(0x05), abi.encode(comparisonStruct));
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/SetUp.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.24;

import {DeployForTest, ODTest, COLLAT, DEBT, TKN} from '@opendollar/test/e2e/Common.t.sol';
import {DeployForTest, ODTest, TKN} from '@opendollar/test/e2e/Common.t.sol';
import {ERC20ForTest} from '@opendollar/test/mocks/ERC20ForTest.sol';
import {ISAFEEngine} from '@opendollar/interfaces/ISAFEEngine.sol';
import {BaseOrderTest} from 'seaport/test/foundry/utils/BaseOrderTest.sol';
Expand Down
4 changes: 1 addition & 3 deletions test/e2e/TestTransferValidationSIP15ZoneOffererTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ import {
CriteriaResolver,
Fulfillment,
FulfillmentComponent,
OrderParameters,
ItemType,
OfferItem,
Order,
OrderComponents,
OrderType
} from 'seaport-types/src/lib/ConsiderationStructs.sol';
import {DeployForTest, ODTest, COLLAT, DEBT, TKN} from '@opendollar/test/e2e/Common.t.sol';
import {ODTest, COLLAT, DEBT, TKN} from '@opendollar/test/e2e/Common.t.sol';

import {UnavailableReason} from 'seaport-sol/src/SpaceEnums.sol';
import {BaseOrderTest} from 'seaport/test/foundry/utils/BaseOrderTest.sol';
Expand Down Expand Up @@ -49,7 +48,6 @@ import {SIP15ZoneEventsAndErrors} from '../../src/interfaces/SIP15ZoneEventsAndE
import {SIP15Zone} from '../../src/contracts/SIP15Zone.sol';
import {SIP15Encoder, Substandard5Comparison} from '../../src/sips/SIP15Encoder.sol';
import {Math, RAY, WAD} from '@opendollar/libraries/Math.sol';
import 'forge-std/console2.sol';

contract TestTransferValidationSIP15ZoneOffererTest is SetUp {
using Math for uint256;
Expand Down

0 comments on commit c4900dc

Please sign in to comment.