Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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 .github/workflows/codecov.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
strategy:
matrix:
node-version:
- 14.x
- 16.x
steps:
- name: Checkout repository
uses: actions/checkout@v2
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/solhint-lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
strategy:
matrix:
node-version:
- 14.x
- 16.x
steps:
- name: Checkout repository
uses: actions/checkout@v2
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/unit-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
strategy:
matrix:
node-version:
- 14.x
- 16.x
steps:
- name: Checkout repository
uses: actions/checkout@v2
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ artifacts
.DS_Store
node_modules
cache
yarn.lock
.env
.idea
package-lock.json
Expand Down
7 changes: 6 additions & 1 deletion contracts/AvalaunchMarketplace.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ contract AvalaunchMarketplace is Initializable {
event PortionListed(address indexed portionOwner, address indexed saleAddress, uint256 portionId);
event PortionRemoved(address indexed portionOwner, address indexed saleAddress, uint256 portionId);
event PortionSold(address indexed portionSeller, address indexed portionBuyer, address indexed saleAddress, uint256 portionId);
event ItemSold(address indexed itemBuyer, uint256 indexed itemId);
event SaleApproved(address indexed sale);
event ApprovedSaleRemoved(address indexed sale);
event FactorySet(ISalesFactory indexed factory);
Expand Down Expand Up @@ -104,13 +105,15 @@ contract AvalaunchMarketplace is Initializable {
* @param sigExpTimestamp is signature expiration timestamp
* @param portions is array of portion ids function caller wants to buy
* @param priceSum is sum of all portion prices
* @param itemId is unique identifier of marketplace item
* @param signature is admin signed data hash which confirms validity of action
*/
function buyPortions(
address sale,
address owner,
uint256 sigExpTimestamp,
uint256 priceSum,
uint256 itemId,
uint256[] calldata portions,
bytes calldata signature
) external payable {
Expand All @@ -120,7 +123,7 @@ contract AvalaunchMarketplace is Initializable {
require(address(msg.sender) != owner, "Can't purchase your own portions.");
{
// Compute signed message hash
bytes32 msgHash = keccak256(abi.encodePacked(owner, msg.sender/*buyer*/, sale, portions, priceSum, sigExpTimestamp, "buyPortions"));
bytes32 msgHash = keccak256(abi.encodePacked(owner, msg.sender/*buyer*/, sale, portions, priceSum, itemId, sigExpTimestamp, "buyPortions"));
// Make sure provided signature is signed by admin and containing valid data
verifySignature(msgHash, signature);
}
Expand Down Expand Up @@ -151,6 +154,8 @@ contract AvalaunchMarketplace is Initializable {
bytes("Your portion(s) just got sold! Greetings from Avalaunch Team :)")
);
require(success);
// Trigger event
emit ItemSold(msg.sender, itemId);
}

/**
Expand Down
9 changes: 6 additions & 3 deletions contracts/sales/AvalaunchSaleV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,9 @@ contract AvalaunchSaleV2 is Initializable {
// Set portion vesting precision
portionVestingPrecision = _portionVestingPrecision;
registrationDepositAVAX = _registrationDepositAVAX;
oneTokenInWei = uint(10) ** IERC20Metadata(address(_token)).decimals();
if(address(_token) != address(0x0)) {
oneTokenInWei = uint(10) ** IERC20Metadata(address(_token)).decimals();
}

// Emit event
emit SaleCreated(
Expand Down Expand Up @@ -344,6 +346,7 @@ contract AvalaunchSaleV2 is Initializable {
{
require(address(saleToken) != address(0));
require(!sale.tokensDeposited, "Tokens already deposited.");
oneTokenInWei = uint(10) ** IERC20Metadata(address(saleToken)).decimals();
sale.token = saleToken;
}

Expand Down Expand Up @@ -440,7 +443,7 @@ contract AvalaunchSaleV2 is Initializable {
function depositTokens() external onlyModerator {
// Require that setSaleParams was called
require(
sale.isCreated &&
sale.isCreated &&
address(sale.token) != address(0) &&
!sale.tokensDeposited
);
Expand Down Expand Up @@ -518,7 +521,7 @@ contract AvalaunchSaleV2 is Initializable {
) internal {
// Make sure selected phase is ongoing and is round phase (Validator, Staking, Booster)
require(phaseId > uint8(Phases.Registration) && phaseId == uint8(sale.phase), "Invalid phase.");

bool isBooster = phaseId == uint8(Phases.Booster);

// Load participation storage pointer
Expand Down
15 changes: 9 additions & 6 deletions deployments/contract-addresses.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"FarmingXavaV2": "0x6E125b68F0f1963b09add1b755049e66f53CC1EA",
"DevTokenAlloStaking": "0x281e9179CE50b951b77d3B0D92456BD3e4F5430A",
"Admin": "0x68c58e1107bcE9be240aF941151d42101086AF56",
"SalesFactory": "0x29F351cdd647195553263924Cc3Abb017CB7fC7b",
"SalesFactory": "0x2d37e5d424Cd24D374253e58E54bA8ee395B0E2F",
"AllocationStaking": "0x897e8265454fd44CAC7D739827d6b46BF1D6A8ff",
"AllocationStakingProxy": "0xA6A01f4b494243d84cf8030d982D7EeB2AeCd329",
"ProxyAdmin": "0x951aa264D7E6a1C267C24c250293e901b89D29e3",
Expand Down Expand Up @@ -68,9 +68,9 @@
"AirdropALOT": "0x7D53D45B6d929662b5586Db2DBD52068C5176655",
"AirdropDFIAT": "0x7f9ec1DE861f16fB9218E6fe86b83359b8b9c294",
"AirdropDEG": "0xFA5D23292f1D6bCc3C4C0A698417a6479B5303BF",
"AvalaunchCollateral": "0xa95dA4598D509f621f45d8b97283928BD0815CA4",
"AvalaunchCollateral": "0x8b1966e6383958395C52D3e8d49FadfE6d9C42b4",
"AvalaunchCollateralProxy": "0x7E5f6AB97EEf4f28900Dc0F713EB99d3c077BBda",
"Sale-Implementation": "0xEA3283F19a56ABB2640B704B2905606C9577f75a",
"Sale-Implementation": "0x4e05033e96ecb624507835ffccB451ecEa1e7156",
"AirdropLOST": "0xacBA2f42B7fA9124f119d7A9E7aC02b58bf9204d",
"AirdropBPT": "0xF3aa6B4A79e6Cab92b80B6866147d0E775a700A4",
"AirdropXAVA-Portion-1": "0x6818eDffA6367e7EE365047BB711AF2E180e9dD3",
Expand Down Expand Up @@ -98,7 +98,10 @@
"AirdropXAVA-Portion-23": "0xf001d3fe81F45Cc47e6cd94c8eA130dDD128a68f",
"AirdropXAVA-Portion-24": "0x98873638a695dc8b5443BdfC704191387d788C9D",
"AirdropXAVA-Portion-25": "0x306A7750f0A861214A4f1413822b6F3A12767E89",
"AirdropXAVA-Portion-26": "0x6d1C24cFC33e2df39223e6bd4d7FA000e3cCA450"
"AirdropXAVA-Portion-26": "0x6d1C24cFC33e2df39223e6bd4d7FA000e3cCA450",
"AvalaunchMarketplace": "0xb6D16bD6872A67B285853664Ef1f1149ba6F223A",
"AvalaunchMarketplaceProxy": "0x863C5AAD62c8086746d03E10A7b327504E154f08",
"Deepwaters": "0x60D57fE620DBCf7d8D96b8BcfBF504fD3135Ec42"
},
"local": {
"MOCK-XAVA": "0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1",
Expand All @@ -121,8 +124,8 @@
"LatestSale": "0x69CCb83b538902abFa576E7429c40B12bB066177",
"AvalaunchCollateral": "0x739B226fa938BF0cA5F1BF49E4F89104fE226073",
"AvalaunchCollateralProxy": "0x3F6715c77B978fb7824a64BBBB502bbB09EcA00b",
"Sale-Implementation": "0x5c8eAd5829c53FBBB1740b3ab2B0fF1670555f7A",
"AvalaunchMarketplace": "0xCF6000A4419a6Ea448f3F951ed6B5273c7406cD1",
"Sale-Implementation": "0x5C69d6694605791D334D596b833D8d04922Cd648",
"AvalaunchMarketplace": "0x60ff7152dBAaD8702f037900505eb33aCbaEdB79",
"AvalaunchMarketplaceProxy": "0xda7C53E855f188038FBAeC9fca07130ac5842468"
}
}
2 changes: 1 addition & 1 deletion hardhat.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ module.exports = {
},
mainnet: {
url: 'https://api.avax.network/ext/bc/C/rpc',
gasPrice: 40000000000,
gasPrice: 30000000000,
chainId: 43114,
timeout: 900000000,
accounts: [process.env.PK || testPK]
Expand Down
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"version": "1.0.0",
"description": "",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "npx hardhat test --network hardhat",
"coverage": "npx hardhat coverage --network hardhat --testfiles test/",
"lint": "npx solhint contracts/**/*.sol"
},
"keywords": [],
"author": "",
Expand All @@ -19,7 +21,8 @@
"hardhat-contract-sizer": "2.5.0",
"hardhat-gas-reporter": "1.0.8",
"hardhat-web3": "1.0.1",
"scrypt": "github:barrysteyn/node-scrypt#fb60a8d3c158fe115a624b5ffa7480f3a24b03fb"
"scrypt": "github:barrysteyn/node-scrypt#fb60a8d3c158fe115a624b5ffa7480f3a24b03fb",
"solhint": "^3.4.0"
},
"devDependencies": {
"@chainlink/contracts": "0.0.10",
Expand Down
27 changes: 9 additions & 18 deletions scripts/configs/saleConfig.json
Original file line number Diff line number Diff line change
@@ -1,28 +1,19 @@
{
"mainnet": {
"tokenAddress": "0xFd538CA3f58dC309dA55B11f007ff53fb4602876",
"totalTokens": "4687500",
"tokenPriceInUSD": "0.05333",
"tokenPriceInAvax": "0.00298934977",
"saleOwner": "0x4F92C01bBfe5918f0FC0bdfE4Af6f7edD1eD85A5",
"registrationStartAt": 1664118000,
"registrationLength": 702000,
"delayBetweenRegistrationAndSale": 43200,
"validatorRoundLength": 32400,
"stakingRoundLength": 54000,
"boosterRoundLength": 16200,
"TGE": "1665243000",
"saleName": "Deepwaters",
"saleEndTime": "1676543400",
"tokenAddress": "0x0000000000000000000000000000000000000000",
"totalTokens": "2083333.33",
"tokenPriceInAvax": "0.0059850374",
"portionVestingPrecision": 100000,
"stakingRoundId": 2,
"registrationDepositAVAX": "1",
"maxVestingTimeShift": 2592000,
"updateTokenPriceInAVAXPercentageThreshold": 30,
"updateTokenPriceInAVAXTimeLimit": 600,
"unlockingTimes": [
1665243000
1676894400,
1679313600
],
"portionPercents": [
100000
50000,
50000
]
},
"mainnet-gold": {
Expand Down
20 changes: 20 additions & 0 deletions scripts/deployment/deploy_marketplace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const hre = require("hardhat");
const { saveContractAddress} = require('../utils');

async function main() {
const marketplaceFactory = await hre.ethers.getContractFactory("AvalaunchMarketplace");
const marketplace = await marketplaceFactory.deploy();
await marketplace.deployed();

console.log(`Marketplace implementation address: ${marketplace.address}`);
saveContractAddress(hre.network.name, "AvalaunchMarketplace", marketplace.address);
}

// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});
97 changes: 97 additions & 0 deletions scripts/deployment/deploy_sales_v2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
const { ethers, network } = require("hardhat");
const { getSavedContractAddresses, saveContractAddress } = require('../utils');
const { greenOut, boldOut } = require('../styling');
const config = require("../configs/saleConfig.json");

const delay = ms => new Promise(res => setTimeout(res, ms));
const delayLength = 3000;

const main = async () => {

const contracts = getSavedContractAddresses()[network.name];
const c = config[network.name];

// instantiate salesFactory
const salesFactory = await ethers.getContractAt('SalesFactory', contracts['SalesFactory']);

// deploy new sale and await the block after
await (await salesFactory.deploySale()).wait();
console.log(boldOut('Sale deployed successfully.'));

// retrieve the sale deployed and save the address
const lastDeployedSale = await salesFactory.getLastDeployedSale();
saveContractAddress(network.name, c['saleName'], lastDeployedSale);
console.log(`Deployed sale address: ${greenOut(lastDeployedSale)}`);

console.log('Sale setup:');
// instantiate deployed sale contract
const sale = await ethers.getContractAt('AvalaunchSaleV2', lastDeployedSale);
console.log(' - Successfully instantiated sale contract.');

// compute the states for a new sale
const saleEndTime = c['saleEndTime'];
const token = c['tokenAddress'];
const registrationDepositAVAX = ethers.utils.parseEther(c['registrationDepositAVAX']);
// token amount & pricing
const tokenPriceInAvax = ethers.utils.parseEther(c['tokenPriceInAvax']);
const totalTokens = ethers.utils.parseEther(c['totalTokens']);
// vesting
const portionVestingPrecision = c['portionVestingPrecision'];
const unlockingTimes = c['unlockingTimes'];
const percents = c['portionPercents'];

// set proper sale parameters
await(await sale.setSaleParams(
token,
tokenPriceInAvax,
totalTokens,
saleEndTime,
portionVestingPrecision,
registrationDepositAVAX
)).wait();
console.log(' - Sale params set successfully.');
await delay(delayLength);

// set vesting parameters
await sale.setVestingParams(unlockingTimes, percents);
console.log(' - Vesting parameters set successfully.');
await delay(delayLength);

// add dexalot portfolio support
await sale.setAndSupportDexalotPortfolio(c['dexalotPortfolio'], c['dexalotUnlockingTime'])
.then(() => console.log(greenOut('Dexalot supported.')))
.catch((err) => console.log(redOut('Dexalot not supported.')));

console.log("Config:");
console.log({
sale: lastDeployedSale,
token,
tokenPriceInAvax,
totalTokens,
saleEndTime,
tokensUnlockTime,
registrationDepositAVAX,
unlockingTimes,
percents
});

const marketplace = await ethers.getContractAt("AvalaunchMarketplace", contracts['AvalaunchMarketplaceProxy']);
await marketplace.approveSale(sale.address)
.then(() => console.log(' - Sale approved on marketplace'))
.catch((err) => console.log(' - Marketplace whitelist failed.'));


const collateral = await ethers.getContractAt("AvalaunchCollateral", contracts['AvalaunchCollateralProxy']);
await collateral.approveSale(sale.address)
.then(() => console.log(' - Sale approved on collateral'))
.catch((err) => console.log(' - Collateral whitelist failed.'));

console.log(boldOut('Done!'));
}

main()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});
Loading