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

add booster for rewards #867

Merged
merged 3 commits into from
Aug 13, 2024
Merged
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
85 changes: 85 additions & 0 deletions contracts/rewards/Booster.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright BigchainDB GmbH and Ocean Protocol contributors
// SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
// Code is Apache-2.0 and docs are CC-BY-4.0

pragma solidity ^0.8.26;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

/**
* @title Booster
*
* @dev Booster is an soul bound ERC721 used to calculate
* incentives boost rate for an address.
* Only owner can mint
*/

contract Booster is Ownable, ERC721Enumerable,ERC721URIStorage {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
uint256 public immutable boost;
constructor(string memory _name, string memory _symbol,uint256 _boost)

Check notice

Code scanning / Slither

Local variable shadowing Low

Check notice

Code scanning / Slither

Local variable shadowing Low

ERC721(_name, _symbol) {
boost=_boost;
}

function tokenURI(uint256 tokenId)
public
view
override(ERC721, ERC721URIStorage)
returns (string memory)
{
return super.tokenURI(tokenId);
}
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC721, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize)
internal
override(ERC721,ERC721Enumerable)
{
require(from == address(0), "Token not transferable");
super._beforeTokenTransfer(from, to, tokenId, batchSize);
}

function _createBoost(address user, string memory tokenURI) private returns (uint256) {

Check notice

Code scanning / Slither

Local variable shadowing Low

_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(user, newItemId);
_setTokenURI(newItemId, tokenURI);
return newItemId;
}

function createBoost(address user, string memory tokenURI) external onlyOwner returns (uint256) {

Check notice

Code scanning / Slither

Local variable shadowing Low

return(_createBoost(user,tokenURI));
}


/**
* @notice Batch Mint only for owner
*/
function batchCreateBoosts(address[] memory user,string[] memory tokenURI) external onlyOwner

Check notice

Code scanning / Slither

Local variable shadowing Low

{
uint256 i;
require(user.length==tokenURI.length);
for(i=0;i<user.length;i++){
_createBoost(user[i],tokenURI[i]);
}
}

// The following functions are overrides required by Solidity.
function _burn(uint256 tokenId) internal override(ERC721URIStorage,ERC721) {
revert("Burning not allowed");
}


}
9 changes: 9 additions & 0 deletions hardhat.config.barge.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ module.exports = {
},
},
},
{
version: "0.8.26",
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},

],
overrides: {},
Expand Down
9 changes: 9 additions & 0 deletions hardhat.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ module.exports = {
},
},
},
{
version: "0.8.26",
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},

],
overrides: {},
Expand Down
93 changes: 93 additions & 0 deletions test/unit/rewards/Booster.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
const { expect } = require('chai');
const { ethers } = require("hardhat");
const { json } = require('hardhat/internal/core/params/argumentTypes');

let metadata = {"uptime":100,"image":"ipfs://123"}
let signers
// Start test block
describe('Booster tests', function () {
before(async function () {
this.boost=1.5
this.tokenID=0
this.boosterContract = await ethers.getContractFactory('Booster');
this.boosterContract = await this.boosterContract.deploy("Booster","B1.5",ethers.utils.parseUnits(String(this.boost)));
await this.boosterContract.deployed();

// Get the contractOwner and collector address
signers = await ethers.getSigners();

});


// Test cases
it('Check booster collection name', async function () {
expect(await this.boosterContract.name()).to.exist;

});

it('Check booster value', async function () {
expect(await this.boosterContract.boost()).to.equal(ethers.utils.parseUnits(String(this.boost)))

});

it('Check booster collection symbol', async function () {
expect(await this.boosterContract.symbol()).to.exist;
});


it('Mints one token, using createBoost', async function () {
await this.boosterContract.createBoost(signers[0].address,JSON.stringify(metadata));
this.tokenID++;
expect(await this.boosterContract.balanceOf(signers[0].address)).to.equal(1);
expect(await this.boosterContract.ownerOf(this.tokenID)).to.equal(signers[0].address);
});

it('Mints several tokens, using batchCreateBoosts', async function () {
const addresses=[]
const tokenURIs=[]

for (let i = 1; i < 4; i++) {
addresses.push(signers[i].address)
tokenURIs.push(JSON.stringify(metadata))
}
await this.boosterContract.batchCreateBoosts(addresses,tokenURIs);
expect(await this.boosterContract.balanceOf(signers[1].address)).to.equal(1);
expect(await this.boosterContract.ownerOf(2)).to.equal(signers[1].address);

//signer[4] should not have any nft
expect(await this.boosterContract.balanceOf(signers[4].address)).to.equal(0);
});


it('Only owner can mint', async function () {
await expect(
this.boosterContract.connect(signers[1])
.createBoost(signers[0].address,JSON.stringify(metadata)))
.to.be.revertedWith("Ownable: caller is not the owner")

await expect(
this.boosterContract.connect(signers[1])
.batchCreateBoosts([signers[0].address,signers[1].address],[JSON.stringify(metadata),JSON.stringify(metadata)]))
.to.be.revertedWith("Ownable: caller is not the owner")
});

it('Is able to query the NFT tokenURI', async function () {
expect(await this.boosterContract.tokenURI(1)).to.equal(JSON.stringify(metadata));
});

it('Emits a transfer event for newly minted NFTs', async function () {
await expect(this.boosterContract.createBoost(signers[1].address,JSON.stringify(metadata)))
.to.emit(this.boosterContract, "Transfer")
.withArgs("0x0000000000000000000000000000000000000000", signers[1].address, 5);
});

it('Is not able to transfer NFTs to another wallet when called by user', async function () {
await expect(this.boosterContract["safeTransferFrom(address,address,uint256)"](signers[0].address,signers[2].address,1)).to.be.revertedWith("Token not transferable");
});

it('Is not able to transfer NFTs to another wallet when called by contract owner', async function () {
await expect(this.boosterContract["safeTransferFrom(address,address,uint256)"](signers[0].address,signers[1].address,2)).to.be.revertedWith("ERC721: caller is not token owner or approved");
});


});
Loading