-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ddec006
commit 8ce5498
Showing
72 changed files
with
21,809 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Deploying Contracts to Live Network | ||
|
||
Follow `README.md` until "Setup". This guide is for deploying to live networks. For deploying to a local network, loosely follow the items in `README.md`. | ||
|
||
### Deploying to Testnet | ||
|
||
Set the env var `POLYGON_NETWORK` to be "mumbai". | ||
Move on to General Deployment. | ||
|
||
### Deploying to Mainnet | ||
|
||
Set the env var `POLYGON_NETWORK` to be "mainnet". | ||
Move on to General Deployment. | ||
|
||
## General Deployment | ||
|
||
Follow each of the subheadings below in order. | ||
|
||
### Compile contracts | ||
|
||
Run `yarn compile` | ||
|
||
### Set signing private key | ||
|
||
Deploying contracts and signing transactions with a keystore file is currently/temporarily unsupported. | ||
This means you must set the env var `USING_KEYSTORE` to be "0", its default. | ||
The env var `HIGHLIGHT_PRIVATE_KEY` must be set to the private key of the account you want to deploy contracts and sign permissioned transactions with. | ||
|
||
### Configure Bundlr | ||
|
||
Configure bundlr if you plan to post token metadata on Arweave. This corresponds to the command `yarn mint:new:store`. Skip this section otherwise. | ||
|
||
Choose between arweave and matic as currencies to fund your bundlr account with. | ||
Set `METADATA_STORAGE_FUND_CURRENCY` to either "arweave" or "matic". Follow instructions in `sample.env` / `.env` to set the recommended value for `METADATA_STORAGE_FUND_RUNNING_BALANCE` in correspondence to the set value for | ||
`METADATA_STORAGE_FUND_CURRENCY`. If your chosen currency is arweave, the scripts will expect a `arweave-private-key.json` file in your root directory - this is your Arweave json web keyfile. | ||
|
||
If this is your first time deploying, it is likely that your bundlr account isn't funded. You can use the CLI to fund your chosen account (if matic, then the account associated with your signing private key. if arweave, then the account associated with your json web keyfile): https://docs.bundlr.network/docs/client/cli. You may have to wait up to an hour. Once you've funded your bundlr account once, the code will keep a running balance, ensuring your bundlr account is always well funded - this means every time you run `yarn mint:new:store` you will pay with the currency you chose. You can always withdraw your funds from your bundlr account. | ||
|
||
### Set better JSON-RPC urls | ||
|
||
The `.env` / `sample.env` file's default values for `POLYGON_TESTNET_URL` and `POLYGON_MAINNET_URL` are public rpc urls. It is ***highly*** recommended that you change these to private rpc urls. You can retrieve these by constructing accounts on services that provide hosted polygon nodes. Examples are https://www.alchemy.com/ and https://maticvigil.com/. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
# Environment Setup | ||
|
||
### Install [nvm](https://github.com/nvm-sh/nvm) | ||
``` | ||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash | ||
``` | ||
|
||
### Install and use the correct version of node, yarn, and dependencies | ||
``` | ||
nvm install 14.17 | ||
nvm use 14.17 | ||
npm install yarn | ||
yarn install | ||
``` | ||
|
||
### Configure environment | ||
``` | ||
cp sample.env .env | ||
``` | ||
|
||
# Setup | ||
|
||
This project uses the `.env` file to determine network, signers, private keys, and more. `sample.env` is pre-configured for a local ethereum instance. | ||
Advanced users can modify the `.env` to interact with / deploy contracts on testnet/mainnet. | ||
|
||
### Start a local hardhat network | ||
``` | ||
yarn local | ||
``` | ||
|
||
### Compile contracts and generate ABIs | ||
``` | ||
yarn compile | ||
``` | ||
|
||
Compiled artifacts will be saved in the `artifacts/` directory. ABIs for each contract can be found | ||
under the `contracts` subdirectory, with the locations of the json artifacts for each contract mirroring | ||
their locations in `contracts/`. | ||
|
||
This command will need to be run after freshly pulling the repository and after pulling in changes to the contracts. | ||
|
||
### Tests | ||
|
||
To run tests: | ||
|
||
``` | ||
yarn test | ||
``` | ||
|
||
To generate test coverage: | ||
|
||
``` | ||
yarn coverage | ||
``` | ||
|
||
### Linter | ||
|
||
Diagnostic: | ||
|
||
``` | ||
yarn lint | ||
``` | ||
|
||
Fixing with linter: | ||
|
||
``` | ||
yarn lint:fix | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
// SPDX-License-Identifier: MIT | ||
// OpenZeppelin Contracts v4.4.1 (proxy/beacon/BeaconProxy.sol) | ||
|
||
pragma solidity 0.8.10; | ||
|
||
import "@openzeppelin/contracts/proxy/beacon/IBeacon.sol"; | ||
import "@openzeppelin/contracts/proxy/Proxy.sol"; | ||
import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol"; | ||
import "../utils/IAccessControlUpgradeable.sol"; | ||
|
||
/** | ||
* @dev This contract implements a proxy that gets the implementation address for each call from a {UpgradeableBeacon}. | ||
* | ||
* The beacon address is stored in storage slot `uint256(keccak256('eip1967.proxy.beacon')) - 1`, so that it doesn't | ||
* conflict with the storage layout of the implementation behind the proxy. | ||
* | ||
* _Available since v3.4._ | ||
*/ | ||
contract BeaconProxy is Proxy, ERC1967Upgrade { | ||
/** | ||
* @dev Initializes the proxy with `beacon`. | ||
* | ||
* If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. This | ||
* will typically be an encoded function call, and allows initializating the storage of the proxy like a Solidity | ||
* constructor. | ||
* | ||
* Requirements: | ||
* | ||
* - `beacon` must be a contract with the interface {IBeacon}. | ||
*/ | ||
constructor(address beacon, bytes memory data) payable { | ||
assert(_BEACON_SLOT == bytes32(uint256(keccak256("eip1967.proxy.beacon")) - 1)); | ||
_upgradeBeaconToAndCall(beacon, data, false); | ||
} | ||
|
||
/** | ||
@dev Upgrades the beacon this proxy points to, to `newBeacon` | ||
* | ||
* If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. | ||
* | ||
* Requirements: | ||
* | ||
* - caller must hold DEFAULT_ADMIN_ROLE on community | ||
* - `newBeacon` must be a contract. | ||
* - The implementation returned by `beacon` must be a contract. | ||
*/ | ||
function upgradeBeaconToAndCall( | ||
address newBeacon, | ||
bytes memory data, | ||
bool forceCall | ||
) external { | ||
bytes memory canUpdateData = Address.functionDelegateCall( | ||
_implementation(), | ||
abi.encodeWithSelector(IAccessControlUpgradeable(address(0)).hasRole.selector, 0x00, msg.sender) | ||
); | ||
bool canUpdate = abi.decode(canUpdateData, (bool)); | ||
require(canUpdate, "Unauthorized"); | ||
_upgradeBeaconToAndCall(newBeacon, data, forceCall); | ||
} | ||
|
||
/** | ||
* @dev Changes the proxy to use a new beacon. Deprecated: see {_upgradeBeaconToAndCall}. | ||
* | ||
* If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. | ||
* | ||
* Requirements: | ||
* | ||
* - `beacon` must be a contract. | ||
* - The implementation returned by `beacon` must be a contract. | ||
*/ | ||
function _setBeacon(address beacon, bytes memory data) internal virtual { | ||
_upgradeBeaconToAndCall(beacon, data, false); | ||
} | ||
|
||
/** | ||
* @dev Returns the current beacon address. | ||
*/ | ||
function _beacon() internal view virtual returns (address) { | ||
return _getBeacon(); | ||
} | ||
|
||
/** | ||
* @dev Returns the current implementation address of the associated beacon. | ||
*/ | ||
function _implementation() internal view virtual override returns (address) { | ||
return IBeacon(_getBeacon()).implementation(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity 0.8.10; | ||
|
||
import "../utils/ReentrancyGuardUpgradeable.sol"; | ||
import "../utils/ERC165/ERC165Upgradeable.sol"; | ||
import "../utils/ERC165/ERC165CheckerUpgradeable.sol"; | ||
import "../utils/EnumerableSetUpgradeable.sol"; | ||
import "../utils/SafeMathUpgradeable.sol"; | ||
|
||
import "./interfaces/ICommunity.sol"; | ||
import "../token_manager/V2/interfaces/ITokenManager2.sol"; | ||
|
||
/** | ||
* @title Highlight community | ||
* @author [email protected] | ||
* @dev Highlight communities must extend this | ||
*/ | ||
abstract contract Community is ERC165Upgradeable, ICommunity, ReentrancyGuardUpgradeable { | ||
using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet; | ||
using AddressUpgradeable for address; | ||
using ERC165CheckerUpgradeable for address; | ||
|
||
/** | ||
* @notice Community name | ||
*/ | ||
string public name; | ||
|
||
/** | ||
* @dev Tracks registered token managers | ||
*/ | ||
EnumerableSetUpgradeable.AddressSet internal _tokenManagers; | ||
|
||
/** | ||
* @dev Tracks which token managers manage what tokens | ||
*/ | ||
mapping(uint256 => address) internal _tokenToManager; | ||
|
||
/** | ||
* @dev Tracks tokens' uris | ||
*/ | ||
mapping(uint256 => string) internal _tokenURI; | ||
|
||
/** | ||
* @dev Tracks number of membership token types | ||
*/ | ||
uint128 internal _membershipTokenCount; | ||
|
||
/** | ||
* @dev Number of tokens allotted before alternating scheme | ||
*/ | ||
uint128 internal constant _MEMBERSHIP_TOKEN_LIMIT = 100; | ||
|
||
/** | ||
* @dev Tracks number of benefit token types | ||
*/ | ||
uint256 internal _benefitTokenCount; | ||
|
||
/** | ||
* @dev Only allows registered token managers to perform action | ||
* @param tokenManager Requesting token manager | ||
*/ | ||
modifier tokenManagerRequired(address tokenManager) { | ||
require(_tokenManagers.contains(tokenManager), "Unregistered token manager"); | ||
_; | ||
} | ||
|
||
/** | ||
* @dev See {ICommunity-tokenManagers}. | ||
*/ | ||
function tokenManagers() external view override returns (address[] memory) { | ||
return _tokenManagers.values(); | ||
} | ||
|
||
/** | ||
* @dev See {ICommunity-tokenManagerBatch} | ||
*/ | ||
function tokenManagerBatch(uint256[] calldata tokenIds) external view override returns (address[] memory) { | ||
address[] memory tokenManagersBatch = new address[](tokenIds.length); | ||
|
||
for (uint256 i = 0; i < tokenIds.length; i++) { | ||
tokenManagersBatch[i] = _tokenToManager[tokenIds[i]]; | ||
} | ||
|
||
return tokenManagersBatch; | ||
} | ||
|
||
/** | ||
* @dev See {ICommunity-uriBatch} | ||
*/ | ||
function uriBatch(uint256[] calldata tokenIds) external view override returns (string[] memory) { | ||
string[] memory urisBatch = new string[](tokenIds.length); | ||
|
||
for (uint256 i = 0; i < tokenIds.length; i++) { | ||
urisBatch[i] = _tokenURI[tokenIds[i]]; | ||
} | ||
|
||
return urisBatch; | ||
} | ||
|
||
/** | ||
* @dev See {IERC165-supportsInterface}. | ||
*/ | ||
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable) returns (bool) { | ||
return interfaceId == type(ICommunity).interfaceId || super.supportsInterface(interfaceId); | ||
} | ||
|
||
/** | ||
* @dev Registers a token manager. | ||
* Emits {TokenManagerRegistered}. | ||
* @param tokenManager Registered token manager | ||
*/ | ||
function _registerTokenManager(address tokenManager, address sender) internal { | ||
require(tokenManager != address(this), "Invalid address"); | ||
require(tokenManager.isContract(), "Not contract"); | ||
require(tokenManager.supportsInterface(type(ITokenManager2).interfaceId), "Not token manager"); | ||
require(!_tokenManagers.contains(tokenManager), "Already registered"); | ||
|
||
_tokenManagers.add(tokenManager); | ||
emit TokenManagerRegistered(tokenManager, sender); | ||
} | ||
|
||
/** | ||
* @dev Set a token's manager | ||
* Emits {TokenManagerSet}. | ||
* @param tokenId Token who's manager is set | ||
* @param _tokenManager Set token manager | ||
*/ | ||
function _setTokenManager( | ||
uint256 tokenId, | ||
address _tokenManager, | ||
address sender | ||
) internal { | ||
_tokenToManager[tokenId] = _tokenManager; | ||
emit TokenManagerSet(tokenId, _tokenManager, sender); | ||
} | ||
} |
Oops, something went wrong.