Skip to content

Commit

Permalink
fix: contractId must be passed by the minter
Browse files Browse the repository at this point in the history
  • Loading branch information
veeso committed Nov 22, 2024
1 parent ce85e7f commit 73c2c19
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 16 deletions.
41 changes: 26 additions & 15 deletions ethereum/contracts/Deferred.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {RewardPool} from "./RewardPool.sol";

// Uncomment this line to use console.log
// import "hardhat/console.sol";
import "hardhat/console.sol";

contract Deferred is ERC721, Ownable {
struct SellerRequest {
Expand All @@ -18,6 +18,8 @@ contract Deferred is ERC721, Ownable {

/// @dev Data to create a contract
struct CreateContractRequest {
/// @dev The id of the contract
uint256 contractId;
/// @dev metadata uri pointing to deferred-data canister uri
string metadataUri;
/// @dev Contract sellers
Expand Down Expand Up @@ -60,6 +62,8 @@ contract Deferred is ERC721, Ownable {
uint256 tokenToId;
/// @dev The contract status
bool closed;
/// @dev The contract exists
bool created;
}

/// @dev The sell contracts
Expand All @@ -68,8 +72,8 @@ contract Deferred is ERC721, Ownable {
/// @dev lazy balances
mapping(address => uint256) private lazyBalances;

/// @dev The next sell contract id. ZERO is reserved for non-existing contracts
uint256 private nextSellContractId = 1;
/// @dev list of sell contracts
uint256[] private sellContractIds;

/// @dev The next token id
uint256 private nextTokenId = 0;
Expand Down Expand Up @@ -123,10 +127,16 @@ contract Deferred is ERC721, Ownable {

/// @notice Create a sell contract. Only the minter can call this method
/// @param _request The request to create a contract
/// @return sellContractId The id of the created contract
function createContract(
CreateContractRequest memory _request
) external onlyMinter returns (uint256 sellContractId) {
) external onlyMinter {
// check if the contract is already created
uint256 contractId = _request.contractId;
require(contractId > 0, "Deferred: contractId must be greater than 0");
require(
!sellContracts[contractId].created,
"Deferred: contract is already created"
);
require(rewardPool != address(0), "Deferred: reward pool is not set");
require(
_request.tokensAmount > 0,
Expand Down Expand Up @@ -160,7 +170,6 @@ contract Deferred is ERC721, Ownable {

uint256 tokenFromId = nextTokenId;
uint256 tokenToId = tokenFromId + _request.tokensAmount - 1;
uint256 contractId = nextSellContractId;

// make sellers array
Seller[] memory sellers = new Seller[](_request.sellers.length);
Expand Down Expand Up @@ -192,27 +201,27 @@ contract Deferred is ERC721, Ownable {
sellContract.tokenFromId = tokenFromId;
sellContract.tokenToId = tokenToId;
sellContract.closed = false;
sellContract.created = true;
// push sellers
delete sellContract.sellers;
for (uint256 i = 0; i < sellers.length; i++) {
sellContract.sellers.push(sellers[i]);
}

nextTokenId += _request.tokensAmount;
nextSellContractId += 1;
// add contract id to the list
sellContractIds.push(contractId);

// emit event and return contract id
emit ContractCreated(contractId);

return contractId;
}

/// @notice Close a sell contract
/// @param _contractId The id of the contract to close
function closeContract(uint256 _contractId) external onlyMinter {
require(_contractId > 0, "Deferred: contractId must be greater than 0");
require(
_contractId < nextSellContractId,
sellContracts[_contractId].created,
"Deferred: contract does not exist"
);

Expand Down Expand Up @@ -392,7 +401,7 @@ contract Deferred is ERC721, Ownable {
) internal view returns (address _initialOwner) {
require(_contractId > 0, "Deferred: contractId must be greater than 0");
require(
_contractId < nextSellContractId,
sellContracts[_contractId].created,
"Deferred: contract does not exist"
);
require(
Expand Down Expand Up @@ -449,14 +458,16 @@ contract Deferred is ERC721, Ownable {
uint256 _tokenId
) internal view returns (uint256 contractId) {
// check if the token is in a sell contract
for (uint256 i = 1; i < nextSellContractId; i++) {
SellContract memory sellContract = sellContracts[i];
for (uint256 i = 0; i < sellContractIds.length; i++) {
uint256 thisContractId = sellContractIds[i];
SellContract memory sellContract = sellContracts[thisContractId];
if (
sellContract.tokenFromId <= _tokenId &&
_tokenId <= sellContract.tokenToId &&
!sellContract.closed
!sellContract.closed &&
sellContract.created
) {
return i;
return thisContractId;
}
}

Expand Down
62 changes: 61 additions & 1 deletion ethereum/test/Deferred.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ describe("Deferred", () => {
deploy;

await token.connect(minter).createContract({
contractId: 1,
sellers: [
{
seller: alice.address,
Expand Down Expand Up @@ -101,6 +102,7 @@ describe("Deferred", () => {
deploy;

await token.connect(minter).createContract({
contractId: 1,
sellers: [
{
seller: alice.address,
Expand Down Expand Up @@ -134,6 +136,7 @@ describe("Deferred", () => {
const { token, minter, alice, bob, charlie } = deploy;

await token.connect(minter).createContract({
contractId: 1,
sellers: [
{
seller: alice.address,
Expand All @@ -157,10 +160,55 @@ describe("Deferred", () => {
expect(await token.balanceOf(bob.address)).to.equal(16_000);
});

it("Should not create a contract with a duplicate id", async () => {
const { token, minter, alice, bob, charlie } = deploy;

await token.connect(minter).createContract({
contractId: 1,
sellers: [
{
seller: alice.address,
quota: 60,
},
{
seller: bob.address,
quota: 40,
},
],
metadataUri: "metadataUri",
buyers: [charlie.address],
ekokeReward: 1_000,
tokenPriceUsd: 100,
tokensAmount: 40_000,
});

await expect(
token.connect(minter).createContract({
contractId: 1,
sellers: [
{
seller: alice.address,
quota: 60,
},
{
seller: bob.address,
quota: 40,
},
],
metadataUri: "metadataUri",
buyers: [charlie.address],
ekokeReward: 1_000,
tokenPriceUsd: 100,
tokensAmount: 40_000,
})
).to.be.revertedWith("Deferred: contract is already created");
});

it("Should create a contract with multiple buyers", async () => {
const { token, minter, alice, bob, charlie } = deploy;

await token.connect(minter).createContract({
contractId: 1,
sellers: [
{
seller: alice.address,
Expand All @@ -180,6 +228,7 @@ describe("Deferred", () => {

await expect(
token.connect(minter).createContract({
contractId: 1,
sellers: [
{
seller: alice.address,
Expand All @@ -204,6 +253,7 @@ describe("Deferred", () => {

await expect(
token.connect(owner).createContract({
contractId: 1,
sellers: [
{
seller: alice.address,
Expand All @@ -224,6 +274,7 @@ describe("Deferred", () => {

await expect(
token.connect(minter).createContract({
contractId: 1,
sellers: [
{
seller: alice.address,
Expand All @@ -248,6 +299,7 @@ describe("Deferred", () => {

await expect(
token.connect(minter).createContract({
contractId: 1,
sellers: [
{
seller: alice.address,
Expand All @@ -268,6 +320,7 @@ describe("Deferred", () => {

await expect(
token.connect(minter).createContract({
contractId: 1,
sellers: [
{
seller: alice.address,
Expand All @@ -287,6 +340,7 @@ describe("Deferred", () => {
const { token, minter, alice, bob, charlie } = deploy;

await token.connect(minter).createContract({
contractId: 1,
sellers: [
{
seller: alice.address,
Expand Down Expand Up @@ -319,6 +373,7 @@ describe("Deferred", () => {
const { token, minter, alice, bob, charlie } = deploy;

await token.connect(minter).createContract({
contractId: 1,
sellers: [
{
seller: alice.address,
Expand Down Expand Up @@ -350,6 +405,7 @@ describe("Deferred", () => {
const { token, minter, alice, bob, marketplace } = deploy;

await token.connect(minter).createContract({
contractId: 1,
sellers: [
{
seller: alice.address,
Expand All @@ -376,6 +432,7 @@ describe("Deferred", () => {
const { token, minter, alice, bob, charlie, marketplace } = deploy;

await token.connect(minter).createContract({
contractId: 1,
sellers: [
{
seller: alice.address,
Expand Down Expand Up @@ -410,6 +467,7 @@ describe("Deferred", () => {
const { token, minter, alice, bob, marketplace } = deploy;

await token.connect(minter).createContract({
contractId: 1,
sellers: [
{
seller: alice.address,
Expand All @@ -436,6 +494,7 @@ describe("Deferred", () => {
const { token, minter, alice, bob, charlie, marketplace } = deploy;

await token.connect(minter).createContract({
contractId: 1,
sellers: [
{
seller: alice.address,
Expand All @@ -455,9 +514,10 @@ describe("Deferred", () => {
});

it("Should not allow setApprovalForAll", async () => {
const { token, minter, alice, bob, charlie, marketplace } = deploy;
const { token, minter, alice, bob, charlie } = deploy;

await token.connect(minter).createContract({
contractId: 1,
sellers: [
{
seller: alice.address,
Expand Down
1 change: 1 addition & 0 deletions ethereum/test/Marketplace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ describe("RewardPool", () => {

// create a sell contract
await deferred.connect(minter).createContract({
contractId: 1,
sellers: [
{
seller: seller.address,
Expand Down

0 comments on commit 73c2c19

Please sign in to comment.