Skip to content

Commit

Permalink
Merge pull request #257 from trifle-labs/sol-metadata
Browse files Browse the repository at this point in the history
metadata + anybody updates
  • Loading branch information
okwme authored Aug 11, 2024
2 parents 743f480 + 3d50cf0 commit c20fd7d
Show file tree
Hide file tree
Showing 15 changed files with 344 additions and 222 deletions.
56 changes: 45 additions & 11 deletions contracts/AnybodyProblem.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ contract AnybodyProblem is Ownable, ERC2981 {
uint256 public constant FIRST_SUNDAY_AT_6_PM_UTC = 324000;

bool public paused = false;
uint256 public price = 0.0025 ether;
uint256 public priceToMint = 0.0025 ether;
uint256 public priceToSave = 0 ether;
uint256 public discount = 2;
address payable public proceedRecipient;
address public externalMetadata;
address payable public speedruns;
Expand Down Expand Up @@ -94,9 +96,9 @@ contract AnybodyProblem is Ownable, ERC2981 {
uint256[] memory verifiersTicks,
uint256[] memory verifiersBodies
) {
updateExternalMetadata(externalMetadata_);
updateProceedRecipient(proceedRecipient_);
updateSpeedrunsAddress(speedruns_);
updateExternalMetadata(externalMetadata_);
for (uint256 i = 0; i < verifiers_.length; i++) {
require(verifiersTicks[i] > 0, 'Invalid verifier');
require(verifiers_[i] != address(0), 'Invalid verifier');
Expand Down Expand Up @@ -137,14 +139,16 @@ contract AnybodyProblem is Ownable, ERC2981 {
// NOTE: the only publicly available function that isn't protected by a modifier
function batchSolve(
uint256 runId,
bool alsoMint,
uint256 day,
uint256[] memory tickCounts,
uint[2][] memory a,
uint[2][2][] memory b,
uint[2][] memory c,
uint[][] memory input
) public payable {
require(!paused, 'Contract is paused');
uint256 day = currentDay();
// uint256 day = currentDay(); // TODO: this version does not enforce day for solving, just for minting NFT
if (runId == 0) {
runId = addNewRun(day);
addNewLevelData(runId);
Expand All @@ -163,6 +167,7 @@ contract AnybodyProblem is Ownable, ERC2981 {
for (uint256 i = 0; i < input.length; i++) {
verifyLevelChunk(
runId,
alsoMint,
tickCounts[i],
day,
a[i],
Expand Down Expand Up @@ -247,6 +252,7 @@ contract AnybodyProblem is Ownable, ERC2981 {
}

function genRadius(uint256 index) public pure returns (uint256) {
// uint8[6] memory radii = [36, 27, 23, 19, 15, 11]; // n * 4 + 2 TODO: swtich to x4 on next deployment
uint8[6] memory radii = [36, 27, 22, 17, 12, 7]; // n * 5 + 2
return radii[index % radii.length] * scalingFactor;
}
Expand Down Expand Up @@ -309,6 +315,7 @@ contract AnybodyProblem is Ownable, ERC2981 {

function verifyLevelChunk(
uint256 runId,
bool alsoMint,
uint256 tickCount,
uint256 day,
uint[2] memory a,
Expand Down Expand Up @@ -414,12 +421,11 @@ contract AnybodyProblem is Ownable, ERC2981 {
runs[runId].accumulativeTime += levelData.time;
if (level == LEVELS) {
runs[runId].solved = true;
require(msg.value == price, 'Incorrect payment');
(bool sent, bytes memory data) = proceedRecipient.call{
value: msg.value
}('');
Speedruns(speedruns).__mint(msg.sender, day, 1, '');
emit EthMoved(proceedRecipient, sent, data, msg.value);
if (alsoMint) {
mint(priceToSave + (priceToMint / discount), day);
} else if (priceToSave > 0) {
makePayment(priceToSave);
}
emit RunSolved(
msg.sender,
runId,
Expand All @@ -434,6 +440,26 @@ contract AnybodyProblem is Ownable, ERC2981 {
}
}

function makePayment(uint256 payment) internal {
require(msg.value >= payment, 'Incorrect payment');
require(proceedRecipient != address(0), 'Invalid recipient');
(bool sent, bytes memory data) = proceedRecipient.call{value: payment}(
''
);
emit EthMoved(proceedRecipient, sent, data, payment);
}

function mint(uint256 payment, uint256 day) internal {
require(day == currentDay(), 'Can only mint on the current day');
require(payment == priceToMint, 'Incorrect price');
makePayment(payment);
Speedruns(speedruns).__mint(msg.sender, day, 1, '');
}

function mint() public payable {
mint(msg.value, currentDay());
}

function addToLeaderboard(uint256 runId) internal {
addToFastestByDay(runId);
addToLongestStreak(runId);
Expand Down Expand Up @@ -839,8 +865,16 @@ contract AnybodyProblem is Ownable, ERC2981 {
emit EthMoved(_to, sent, data, amount);
}

function updatePrice(uint256 price_) public onlyOwner {
price = price_;
function updateDiscount(uint256 discount_) public onlyOwner {
discount = discount_;
}

function updatePriceToSave(uint256 priceToSave_) public onlyOwner {
priceToSave = priceToSave_;
}

function updatePriceToMint(uint256 priceToMint_) public onlyOwner {
priceToMint = priceToMint_;
}

function updatePaused(bool paused_) public onlyOwner {
Expand Down
118 changes: 70 additions & 48 deletions contracts/ExternalMetadata.sol
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ contract ExternalMetadata is Ownable {
'"external_url": "https://anybody.trifle.life",',
'"animation_url": "https://anybody-nft.netlify.app/#',
StringsExtended.toString(date),
getBestTimeEncoded(date),
'",',
'"attributes": ',
getAttributes(date),
Expand All @@ -392,6 +393,35 @@ contract ExternalMetadata is Ownable {
);
}

function getBestTimeEncoded(
uint256 date
) public view returns (string memory) {
uint256 bestRunId = AnybodyProblem(anybodyProblem).fastestByDay(
date,
0
);

AnybodyProblem.Level[] memory levels = AnybodyProblem(anybodyProblem)
.getLevelsData(bestRunId);

string memory encoded = '{"levels":[';

for (uint256 i = 0; i < levels.length; i++) {
AnybodyProblem.Level memory level = levels[i];
encoded = string(
abi.encodePacked(
encoded,
'{"events": [{"time":',
StringsExtended.toString(level.time),
'}]}',
(i == levels.length - 1 ? '' : ',')
)
);
}
encoded = Base64.encode(abi.encodePacked(encoded, ']}'));
return string(abi.encodePacked('-', encoded));
}

function getName(uint256 date) public pure returns (string memory) {
(uint year, uint month, uint day) = BokkyPooBahsDateTimeLibrary
.timestampToDate(date);
Expand Down Expand Up @@ -692,62 +722,60 @@ contract ExternalMetadata is Ownable {
return path;
}

function getFastestTime(
uint256 date,
uint256 placeIndex
) public view returns (address, string memory sec) {
uint256 runId = AnybodyProblem(anybodyProblem).fastestByDay(
date,
placeIndex
);
(address player, , uint256 timeCompleted, , ) = AnybodyProblem(
anybodyProblem
).runs(runId);

uint256 precision = 1000;
uint256 fps = 25;
timeCompleted = (timeCompleted * precision) / fps;
uint256 timeSeconds = timeCompleted / precision;
uint256 timeMs = (timeCompleted - timeSeconds * precision) / 10;

return (
player,
string(
abi.encodePacked(
StringsExtended.toString(timeSeconds),
'.',
StringsExtended.toString(timeMs)
)
)
);
}

/// @dev generates the attributes as JSON String
function getAttributes(uint256 date) public view returns (string memory) {
(uint year, uint month, ) = BokkyPooBahsDateTimeLibrary.timestampToDate(
date
);
uint256 fastestRunId = AnybodyProblem(anybodyProblem).fastestByDay(

(address fastestAddress, string memory fastestTime) = getFastestTime(
date,
0
);
uint256 secondFastestRunId = AnybodyProblem(anybodyProblem)
.fastestByDay(date, 1);
uint256 thirdFastestRunId = AnybodyProblem(anybodyProblem).fastestByDay(
date,
2
);
(address fastestAddress, , uint256 fastestTime, , ) = AnybodyProblem(
anybodyProblem
).runs(fastestRunId);
(
address secondFastestAddress,
,
uint256 secondFastestTime,
,

) = AnybodyProblem(anybodyProblem).runs(secondFastestRunId);
string memory secondFastestTime
) = getFastestTime(date, 1);
(
address thirdFastestAddress,
,
uint256 thirdFastestTime,
,

) = AnybodyProblem(anybodyProblem).runs(thirdFastestRunId);

uint256 precision = 1000;
uint256 fps = 25;
fastestTime = (fastestTime * precision) / fps;
uint256 fastestTimeSeconds = fastestTime / precision;
uint256 fastestTimeMs = (fastestTime - fastestTimeSeconds * precision) /
10;

secondFastestTime = (secondFastestTime * precision) / fps;
uint256 secondFastestTimeSeconds = secondFastestTime / precision;
uint256 secondFastestTimeMs = (secondFastestTime -
secondFastestTimeSeconds *
precision) / 10;

thirdFastestTime = (thirdFastestTime * precision) / fps;
uint256 thirdFastestTimeSeconds = thirdFastestTime / precision;
uint256 thirdFastestTimeMs = (thirdFastestTime -
thirdFastestTimeSeconds *
precision) / 10;
string memory thirdFastestTime
) = getFastestTime(date, 2);

return
string(
abi.encodePacked(
'[',
'{"trait_type":"Galaxy","value":"BASED"},',
'{"trait_type":"Day","value":"',
StringsExtended.toString(date),
'"}, {"trait_type":"Year-Month","value":"',
Expand All @@ -758,21 +786,15 @@ contract ExternalMetadata is Ownable {
'"}, {"trait_type":"1st Place","value":"0x',
StringsExtended.toHexString(fastestAddress),
'"}, {"trait_type":"1st Place Time (s)","value":"',
StringsExtended.toString(fastestTimeSeconds),
'.',
StringsExtended.toString(fastestTimeMs),
fastestTime,
'"}, {"trait_type":"2nd Place","value":"0x',
StringsExtended.toHexString(secondFastestAddress),
'"}, {"trait_type":"2nd Place Time (s)","value":"',
StringsExtended.toString(secondFastestTimeSeconds),
'.',
StringsExtended.toString(secondFastestTimeMs),
secondFastestTime,
'"}, {"trait_type":"3rd Place","value":"0x',
StringsExtended.toHexString(thirdFastestAddress),
'"}, {"trait_type":"3rd Place Time (s)","value":"',
StringsExtended.toString(thirdFastestTimeSeconds),
'.',
StringsExtended.toString(thirdFastestTimeMs),
thirdFastestTime,
'"}]'
)
);
Expand Down
28 changes: 14 additions & 14 deletions dist/index.html

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions dist/module.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/module.js.map

Large diffs are not rendered by default.

Loading

0 comments on commit c20fd7d

Please sign in to comment.