Skip to content
Open
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
94 changes: 75 additions & 19 deletions packages/contracts/contracts/CyberDropBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ contract CyberDropBase is CyberTokenBase {

event DropCreated(address indexed account, uint256 indexed tokenId);

modifier noContract() {
require(msg.sender == tx.origin, 'NC');
_;
}

function dropMintCounter(uint256 _tokenId, address _minter)
external
view
Expand Down Expand Up @@ -99,12 +104,11 @@ contract CyberDropBase is CyberTokenBase {
emit DropCreated(sender, tokenId);
}

function mint(
function mintInternal(
uint256 _tokenId,
uint256 _quantity,
bytes memory _signature
) external payable returns (bool success) {
address sender = _msgSender();
address minter
) internal returns (bool success) {
LibDropStorage.Drop storage drop = LibDropStorage.layout().drops[_tokenId];

require(drop.amountCap - drop.minted >= _quantity, 'CR');
Expand All @@ -116,34 +120,86 @@ contract CyberDropBase is CyberTokenBase {

require(msg.value == drop.price * _quantity, 'IA');

uint256 senderDropNonce = drop.mintCounter[sender].current();
// Effects
drop.minted += _quantity;
drop.mintCounter[minter].increment();
_safeMint(minter, _tokenId, _quantity, '');

if (drop.price > 0) {
uint256 amountOnCyber = (msg.value * drop.shareCyber) / 100;
uint256 amountCreator = msg.value - amountOnCyber;

drop.creator.transfer(amountCreator);
payable(LibAppStorage.layout().oncyber).transfer(amountOnCyber);
}

emit Minted(minter, _tokenId, _quantity);

return true;
}

function mint(
uint256 _tokenId,
uint256 _quantity,
bytes memory _signature
) external payable returns (bool success) {
address sender = _msgSender();
uint256 senderDropNonce = LibDropStorage
.layout()
.drops[_tokenId]
.mintCounter[sender]
.current();

bytes memory _message = abi.encodePacked(
_tokenId,
_quantity,
sender,
senderDropNonce
);
LibAppStorage.Layout storage layout = LibAppStorage.layout();
address recoveredAddress = keccak256(_message)
.toEthSignedMessageHash()
.recover(_signature);
require(recoveredAddress == layout.manager, 'NM');
require(recoveredAddress == LibAppStorage.layout().manager, 'NM');

// Effects
drop.minted += _quantity;
drop.mintCounter[sender].increment();
_safeMint(sender, _tokenId, _quantity, '');
return mintInternal(_tokenId, _quantity, sender);
}

if (drop.price > 0) {
uint256 amountOnCyber = (msg.value * drop.shareCyber) / 100;
uint256 amountCreator = msg.value - amountOnCyber;
function mintRandom(uint256[] calldata _tokenIds, bytes memory _signature)
external
payable
noContract
returns (bool success)
{
address sender = _msgSender();
uint256 index = random(_tokenIds.length, sender);

drop.creator.transfer(amountCreator);
payable(layout.oncyber).transfer(amountOnCyber);
}
bytes memory _message = abi.encodePacked(_tokenIds, sender);
address recoveredAddress = keccak256(_message)
.toEthSignedMessageHash()
.recover(_signature);
require(recoveredAddress == LibAppStorage.layout().manager, 'NM');

emit Minted(sender, _tokenId, _quantity);
return mintInternal(_tokenIds[index], 1, sender);
}

return true;
function random(uint256 _max, address _sender)
public
view
returns (uint256 number)
{
uint256 seed = uint256(
keccak256(
abi.encodePacked(
block.timestamp +
block.difficulty +
block.gaslimit +
block.number +
(uint256(keccak256(abi.encodePacked(block.coinbase))) /
block.timestamp) +
(uint256(keccak256(abi.encodePacked(_sender))) / block.timestamp)
)
)
);
return (seed - ((seed / _max) * _max));
}
}
15 changes: 15 additions & 0 deletions packages/contracts/contracts/Test/DropRandomCaller.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

//import 'hardhat/console.sol';
import '../CyberDropBase.sol';

contract DropRandomCaller {
function testMintRandom(
CyberDropBase _cyberDropBase,
uint256[] calldata _tokenIds,
bytes memory _signature
) external payable {
_cyberDropBase.mintRandom{value: msg.value}(_tokenIds, _signature);
}
}
16 changes: 16 additions & 0 deletions packages/contracts/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,19 @@ export async function signMintRequest(

return signer.signMessage(pHash)
}

export async function signMintRandomRequest(
tokenIds: number[],
creator: string,
signer: Signer
): Promise<string> {
const pTokenIds = tokenIds.map((tokenId) =>
utils.hexZeroPad(BigNumber.from(tokenId).toHexString(), 32)
)
const pCreator = utils.arrayify(creator)
const message = utils.concat([...pTokenIds, pCreator])
const hash = utils.keccak256(message)
const pHash = utils.arrayify(hash)

return signer.signMessage(pHash)
}
3 changes: 2 additions & 1 deletion packages/contracts/scripts/mint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ async function main() {
)
const tokenId = 0
const quantity = 1
const mintPrice = await contract.getMintPriceForToken(tokenId)
const drop = await contract.getDrop(tokenId)
const mintPrice = drop.price.mul(quantity)

const signatureMint = await signMintRequest(
tokenId,
Expand Down
50 changes: 50 additions & 0 deletions packages/contracts/scripts/mintRandom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// @ts-ignore-next-line
import { deployments, ethers } from 'hardhat'
import { signMintRandomRequest } from '../lib/utils'

async function main() {
const contractName = 'DiamondCyberDestinationFactory'

const accounts = await ethers.getSigners()
const minter = accounts[3]
const manager = accounts[2]

const Contract = await deployments.get(contractName)
const contract = await ethers.getContractAt(
Contract.abi,
Contract.address,
minter
)
const tokenIds = [1, 2, 3]
const drop = await contract.getDrop(tokenIds[1])
const mintPrice = drop.price

const signatureMintRandom = await signMintRandomRequest(
tokenIds,
minter.address,
manager
)

const estimation = await contract.estimateGas.mintRandom(
tokenIds,
signatureMintRandom,
{
value: mintPrice,
}
)

const tx = await contract.mintRandom(tokenIds, signatureMintRandom, {
value: mintPrice,
gasLimit: estimation.mul(100).div(90),
})

const txReceipt = await tx.wait()
console.log('txReceipt', txReceipt)
}

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