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

Feature/refactor_access_lists #879

Merged
merged 9 commits into from
Sep 3, 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
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = v2.1.0
current_version = v2.2.0
commit = True
tag = True

Expand Down
14 changes: 9 additions & 5 deletions addresses/address.json
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -269,14 +269,16 @@
"1": "0x519d462294958A935D34351b3ad9F98cCAB0b7f8",
"2": "0x2bCa501a6f9FB8a96f1b7B09D4f74A32ACAa7584",
"3": "0xf00c16665b79F23c04e5c8652Fe9853046b987c8",
"4": "0x89b752C3e272feBA17B363EaaBFe0d653cF75bE7"
"4": "0x89b752C3e272feBA17B363EaaBFe0d653cF75bE7",
"5": "0xb4914dfeC7f70C708673620eDF6d8839F81E7612"
},
"ERC721Template": {
"1": "0x9Ab15cc945b2B58A51384539211dE8a88a1355E8"
},
"Dispenser": "0xbde8224d15885c2E46Be665b9392E619cD142de8",
"ERC721Factory": "0x315ef329D214cde5cE7C206104aC35B1fe66bb8c",
"PredictoorHelper": "0x2e4cb19faD077768fDcB04Bc0549AB76BE8eA63F"
"PredictoorHelper": "0x2e4cb19faD077768fDcB04Bc0549AB76BE8eA63F",
"AccessListFactory": "0xdA412123a3Cc0D921bcf7246f8742e3b7c3E7b94"
},
"sepolia": {
"chainId": 11155111,
Expand Down Expand Up @@ -307,7 +309,8 @@
"1": "0xDBDa486d8fE29F75e9Ca858F438b380Fc14b1232",
"2": "0xF6410bf5d773C7a41ebFf972f38e7463FA242477",
"3": "0x1B083D8584dd3e6Ff37d04a6e7e82b5F622f3985",
"4": "0x4dD281EB67DED07E76E413Df16176D66ae69e240"
"4": "0x4dD281EB67DED07E76E413Df16176D66ae69e240",
"5": "0xA4E108a4fa07C931cFe4bF2c1c6f9C1579d5a819"
},
"ERC721Template": {
"1": "0x69B6E54Ad2b3c2801d11d8Ad56ea1d892555b776"
Expand All @@ -316,7 +319,8 @@
"ERC721Factory": "0x80E63f73cAc60c1662f27D2DFd2EA834acddBaa8",
"DFRewards": "0xc37F8341Ac6e4a94538302bCd4d49Cf0852D30C0",
"DFStrategyV1": "0x3c21a90599b5B7f37014cA5Bf30d3f1b73d7e391",
"PredictoorHelper": "0xE9397625Df9B63f0C152f975234b7988b54710B8"
"PredictoorHelper": "0xE9397625Df9B63f0C152f975234b7988b54710B8",
"AccessListFactory": "0x12bB8D85a091A69A07E22E52d4567dBB91568f52"
},
"optimism_sepolia": {
"chainId": 11155420,
Expand Down Expand Up @@ -359,7 +363,7 @@
"Router": "0x4Ede1776D6B75de6c907172Abc0453a3C8AB372a",
"FixedPrice": "0x8372715D834d286c9aECE1AcD51Da5755B32D505",
"ERC20Template": {
"1": "0x02eCd3850B53b1BA8dbCdD146C963cC27f27Dd3C",
"1": "0x02eCd3850B53b1BA8dbCdD146C963cC27f27Dd3C",
"2": "0x23Efb300c8778d6842bB0cCBD07D356eCeB97070"
},
"ERC721Template": {
Expand Down
134 changes: 120 additions & 14 deletions contracts/accesslists/AccessList.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,141 @@
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

/**
* @title AccessList
*
* @dev AccessList is an soul bound ERC721 used to build access lists (allow or deny)
* Only owner can mint and also burn (ie: remove address from a list)
* @dev AccessList is an optional soul bound/non-sould bound
* ERC721 used to build access lists (allow or deny)
* Only owner can mint
* Each token id has it's own metadata
*/

contract AccessList is Ownable, ERC721Enumerable,ERC721URIStorage {
contract AccessList is ERC721Enumerable,ERC721URIStorage {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
bool private initialized;
address private _owner;
string private _name;
Dismissed Show dismissed Hide dismissed
string private _symbol;
Dismissed Show dismissed Hide dismissed
bool public transferable;


event NewAccessList(
address indexed contractAddress,
address indexed owner
);
event AddressAdded(
address indexed wallet,
uint256 tokenId
);
event AddressRemoved(
uint256 tokenId
);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor()
ERC721("","") {

}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}

/**
* @dev Returns the address of the current owner.
*/
function owner() public view returns (address) {
return _owner;
}

/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}

/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public onlyOwner {
_transferOwnership(address(0));
}

constructor(string memory _name, string memory _symbol)
ERC721(_name, _symbol) {
emit NewAccessList(address(this),_msgSender());
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}

/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
/* @dev initialize
* Calls private _initialize function. Only if contract is not initialized.
This function mints an NFT (tokenId=1) to the owner and add owner as Manager Role
* @param owner NFT Owner
* @param name_ NFT name
* @param symbol_ NFT Symbol
* @param transferable_ if set to false, this NFT is non-transferable

@return boolean
*/

function initialize(
address owner_,

Check notice

Code scanning / Slither

Missing zero address validation Low

string calldata name_,
string calldata symbol_,
bool transferable_,
address[] memory user,
string[] memory _tokenURI

Check warning

Code scanning / Slither

Conformance to Solidity naming conventions Warning

) external returns (bool) {
require(
!initialized,
"Already initialized"
);
_name = name_;
_symbol = symbol_;
_owner=owner_;
initialized = true;
transferable = transferable_;
if(user.length==_tokenURI.length && _tokenURI.length>0){
uint256 i;
for(i=0;i<user.length;i++){
_add(user[i],_tokenURI[i]);
}
}
return(true);
}

/**
* @dev name
* It returns the token name.
* @return Datatoken name.
*/
function name() public view override returns (string memory) {
return _name;
}

/**
* @dev symbol
* It returns the token symbol.
* @return Datatoken symbol.
*/
function symbol() public view override returns (string memory) {
return _symbol;
}

function tokenURI(uint256 tokenId)
Expand All @@ -61,7 +166,8 @@
internal
override(ERC721,ERC721Enumerable)
{
require(from == address(0) || to == address(0), "Token not transferable");
if(transferable == false)
require(from == address(0) || to == address(0), "Token not transferable");
super._beforeTokenTransfer(from, to, tokenId, batchSize);
}

Expand Down Expand Up @@ -92,7 +198,7 @@
}

function burn(uint256 tokenId) public {
require(_msgSender() == super.owner() || _msgSender()==super._ownerOf(tokenId),"ERC721: Not owner");
require(_msgSender() == owner() || _msgSender()==super._ownerOf(tokenId),"ERC721: Not owner");
emit AddressRemoved(tokenId);
_burn(tokenId);
}
Expand Down
149 changes: 149 additions & 0 deletions contracts/accesslists/AccessListFactory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
pragma solidity 0.8.12;
// 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

import "../utils/Deployer.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

interface IAccessList{
function initialize(address, string calldata, string calldata,
bool,address[] memory,string[] memory) external returns (bool);
function transferable() external view returns (bool);

}
/**
* @title DTFactory contract
* @author Ocean Protocol Team
*
* @dev Implementation of Ocean datatokens Factory
*
* DTFactory deploys datatoken proxy contracts.
* New datatoken proxy contracts are links to the template contract's bytecode.
* Proxy contract functionality is based on Ocean Protocol custom implementation of ERC1167 standard.
*/
contract AccessListFactory is Deployer, Ownable, ReentrancyGuard {
address templateAddress;
mapping(address => address) public accessListDeployedContracts;

event NewAccessList(
address indexed contractAddress,
address indexed owner
);

/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function _isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.

uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly {
size := extcodesize(account)
}
return size > 0;
}
Comment on lines +52 to +63

Check warning

Code scanning / Slither

Assembly usage Warning

/**
* @dev constructor
* Called on contract deployment. Could not be called with zero address parameters.
* @param _template refers to the address of a deployed access list contract.
*/
constructor(
address _template
) {
require(
_template != address(0) && _isContract(_template),
"Invalid template"
);
templateAddress=_template;
}


/**
* @dev deployAccessListContract
*
* @param name NFT name
* @param symbol NFT Symbol
* @param transferable if NFT is transferable. Cannot be changed afterwards
* @param owner owner of the NFT
* @param user array of users to add on the list
* @param _tokenURI array of uris for each of the users to be added on the list
*/

function deployAccessListContract(
string calldata name,
string calldata symbol,
bool transferable,
address owner,

Check notice

Code scanning / Slither

Local variable shadowing Low

address[] memory user,
string[] memory _tokenURI

Check warning

Code scanning / Slither

Conformance to Solidity naming conventions Warning

) public returns (address token) {
token = deploy(templateAddress);

require(
token != address(0),
"Failed to deploy new access list"
);

accessListDeployedContracts[token] = token;
emit NewAccessList(token,owner);
IAccessList tokenInstance = IAccessList(token);
require(
tokenInstance.initialize(
owner,
name,
symbol,
transferable,
user,
_tokenURI
),
"Unable to initialize access list"
);


}


/**
* @dev change the template address
Only Owner can call it
* @param _newTemplateAddress new template address
*/

// function to activate a disabled token.
function changeTemplateAddress(address _newTemplateAddress) external onlyOwner {

Check warning

Code scanning / Slither

Conformance to Solidity naming conventions Warning

require(
_newTemplateAddress != address(0) && _isContract(_newTemplateAddress),
"Invalid template"
);
templateAddress=_newTemplateAddress;
}

function isDeployed(address contractAddress) public view returns (bool){
if(accessListDeployedContracts[contractAddress] == contractAddress) return true;
return false;
}
function isSoulBound(address contractAddress) external view returns (bool){
require(isDeployed(contractAddress)==true,"Not deployed by factory");
return(!(IAccessList(contractAddress).transferable()));
}
Comment on lines +144 to +147

Check warning

Code scanning / Slither

Boolean equality Warning


}
Loading
Loading