forked from mico/idle_moloch
Fixes prices calculation
This commit is contained in:
parent
b153e4b6bd
commit
b47db1f359
@ -107,9 +107,6 @@ contract RaidGeld is ERC20, Ownable {
|
|||||||
function addUnit(uint8 unit, uint16 n_units) external onlyPlayer {
|
function addUnit(uint8 unit, uint16 n_units) external onlyPlayer {
|
||||||
require(unit <= 3, "Unknown unit");
|
require(unit <= 3, "Unknown unit");
|
||||||
|
|
||||||
// First trigger a raid so player receives what he is due at to this moment
|
|
||||||
performRaid(msg.sender);
|
|
||||||
|
|
||||||
Army storage army = armies[msg.sender];
|
Army storage army = armies[msg.sender];
|
||||||
uint16 currentLevel = 0;
|
uint16 currentLevel = 0;
|
||||||
if (unit == 0) {
|
if (unit == 0) {
|
||||||
@ -128,6 +125,13 @@ contract RaidGeld is ERC20, Ownable {
|
|||||||
|
|
||||||
uint256 cost = RaidGeldUtils.calculateUnitPrice(unit, currentLevel, n_units) * 10 ** decimals();
|
uint256 cost = RaidGeldUtils.calculateUnitPrice(unit, currentLevel, n_units) * 10 ** decimals();
|
||||||
require(balanceOf(msg.sender) > cost, "Not enough GELD to add this much");
|
require(balanceOf(msg.sender) > cost, "Not enough GELD to add this much");
|
||||||
|
|
||||||
|
// TODO: Since we are first minting then burning the token, this could be simplified
|
||||||
|
// by first calculating the difference and then minting / burning in just one operation
|
||||||
|
|
||||||
|
// First trigger a raid so player receives what he is due at to this moment
|
||||||
|
performRaid(msg.sender);
|
||||||
|
// then burn the cost of the new army
|
||||||
_burn(msg.sender, cost);
|
_burn(msg.sender, cost);
|
||||||
|
|
||||||
// Increase level
|
// Increase level
|
||||||
|
|||||||
@ -6,14 +6,14 @@ import {Army} from "../src/RaidGeld.sol";
|
|||||||
library RaidGeldUtils {
|
library RaidGeldUtils {
|
||||||
function calculateUnitPrice(uint8 unit, uint16 currentLevel, uint16 units) internal pure returns (uint256) {
|
function calculateUnitPrice(uint8 unit, uint16 currentLevel, uint16 units) internal pure returns (uint256) {
|
||||||
require(unit <= 3, "No matching unit found");
|
require(unit <= 3, "No matching unit found");
|
||||||
uint256 rollingPriceCalculation = uint256(unit) * 38;
|
uint256 rollingPriceCalculation = uint256(unit + 1) * 38;
|
||||||
uint256 price = 0;
|
uint256 price = rollingPriceCalculation;
|
||||||
|
|
||||||
// Each level costs 15% more than previous
|
// Each level costs 15% more than previous
|
||||||
uint256 PERCENT_INCREASE = 115;
|
uint256 PERCENT_INCREASE = 115;
|
||||||
for (uint256 i = 1; i < currentLevel + units; i++) {
|
for (uint256 i = 1; i < currentLevel + units; i++) {
|
||||||
rollingPriceCalculation = rollingPriceCalculation * PERCENT_INCREASE / 100;
|
rollingPriceCalculation = rollingPriceCalculation * PERCENT_INCREASE / 100;
|
||||||
if (i > currentLevel) {
|
if (i >= currentLevel) {
|
||||||
price += rollingPriceCalculation;
|
price += rollingPriceCalculation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ pragma solidity ^0.8.13;
|
|||||||
|
|
||||||
import {Test, console} from "forge-std/Test.sol";
|
import {Test, console} from "forge-std/Test.sol";
|
||||||
import {RaidGeld, Army, Player} from "../src/RaidGeld.sol";
|
import {RaidGeld, Army, Player} from "../src/RaidGeld.sol";
|
||||||
|
import "../src/RaidGeldUtils.sol";
|
||||||
|
|
||||||
contract raid_geldTest is Test {
|
contract raid_geldTest is Test {
|
||||||
RaidGeld public raid_geld;
|
RaidGeld public raid_geld;
|
||||||
@ -113,23 +114,26 @@ contract raid_geldTest is Test {
|
|||||||
vm.expectRevert();
|
vm.expectRevert();
|
||||||
raid_geld.addUnit(1, 100);
|
raid_geld.addUnit(1, 100);
|
||||||
|
|
||||||
// Add 2 units
|
|
||||||
Army memory army = raid_geld.getArmy(player1);
|
Army memory army = raid_geld.getArmy(player1);
|
||||||
uint256 unit_level = army.moloch_denier.level;
|
uint256 unit_level = army.moloch_denier.level;
|
||||||
uint256 balance = raid_geld.balanceOf(player1);
|
uint256 balance = raid_geld.balanceOf(player1);
|
||||||
uint256 income_per_sec = army.profit_per_second;
|
uint256 income_per_sec = army.profit_per_second;
|
||||||
raid_geld.addUnit(0, 2);
|
|
||||||
|
// Add 1 unit
|
||||||
// TODO: maybe try to test against exact values we want here
|
raid_geld.addUnit(0, 1);
|
||||||
|
uint256 unitPrice = RaidGeldUtils.calculateUnitPrice(0, 0, 1) * 10 ** 4;
|
||||||
|
|
||||||
// Check that those tokens were burnt
|
// Check that those tokens were burnt
|
||||||
|
// WARN: In addUnit will mint additional tokens but they are not calculated
|
||||||
|
// into this because the test doesnt move the blockchain so no extra tokens
|
||||||
|
// are minted to the user
|
||||||
uint256 newBalance = raid_geld.balanceOf(player1);
|
uint256 newBalance = raid_geld.balanceOf(player1);
|
||||||
assertGt(newBalance, balance - 2 * 10 ** 4);
|
assertEq(newBalance, balance - unitPrice);
|
||||||
army = raid_geld.getArmy(player1);
|
army = raid_geld.getArmy(player1);
|
||||||
|
|
||||||
// Check that unit level increased
|
// Check that unit level increased
|
||||||
uint256 new_unit_level = army.moloch_denier.level;
|
uint256 new_unit_level = army.moloch_denier.level;
|
||||||
assertEq(new_unit_level, unit_level + 2);
|
assertEq(new_unit_level, unit_level + 1);
|
||||||
|
|
||||||
// Check that user income per second increased
|
// Check that user income per second increased
|
||||||
uint256 new_income_per_sec = army.profit_per_second;
|
uint256 new_income_per_sec = army.profit_per_second;
|
||||||
@ -143,7 +147,9 @@ contract raid_geldTest is Test {
|
|||||||
// Register player 1
|
// Register player 1
|
||||||
vm.startPrank(player1);
|
vm.startPrank(player1);
|
||||||
registerPlayer();
|
registerPlayer();
|
||||||
raid_geld.addUnit(1, 2);
|
|
||||||
|
// bought 1 moloch_denier
|
||||||
|
raid_geld.addUnit(0, 1);
|
||||||
|
|
||||||
uint256 balance = raid_geld.balanceOf(player1);
|
uint256 balance = raid_geld.balanceOf(player1);
|
||||||
|
|
||||||
|
|||||||
52
test/RaidGeldUtils.t.sol
Normal file
52
test/RaidGeldUtils.t.sol
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.8.13;
|
||||||
|
|
||||||
|
import {Test, console} from "forge-std/Test.sol";
|
||||||
|
import {Army, Raider} from "../src/RaidGeld.sol";
|
||||||
|
import "../src/RaidGeldUtils.sol";
|
||||||
|
|
||||||
|
contract raid_geldTest is Test {
|
||||||
|
function test_0_unit_price() public {
|
||||||
|
// buying 1 unit of moloch_denier
|
||||||
|
uint256 basePriceMolochDenier = RaidGeldUtils.calculateUnitPrice(0, 0, 1);
|
||||||
|
assertEq(basePriceMolochDenier, 38);
|
||||||
|
|
||||||
|
// buying 3 units
|
||||||
|
// has to be a bit more than 3 * 38 = 114
|
||||||
|
uint256 price = RaidGeldUtils.calculateUnitPrice(0, 0, 3);
|
||||||
|
assertGt(price, 3 * basePriceMolochDenier);
|
||||||
|
|
||||||
|
uint256 basePriceChamp = RaidGeldUtils.calculateUnitPrice(0, 0, 3);
|
||||||
|
// buying 3 units of champions
|
||||||
|
// has to be a bit more than 4 * 38 * 3 = 114
|
||||||
|
price = RaidGeldUtils.calculateUnitPrice(3, 0, 3);
|
||||||
|
assertGt(price, 3 * basePriceChamp);
|
||||||
|
|
||||||
|
// buying 12 units of champions when u already have 10
|
||||||
|
price = RaidGeldUtils.calculateUnitPrice(3, 10, 12);
|
||||||
|
// price should scale up
|
||||||
|
assertGt(price, basePriceChamp * 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_1_profits_per_second() public {
|
||||||
|
Army memory army = Army({
|
||||||
|
moloch_denier: Raider({ level: 1}),
|
||||||
|
apprentice: Raider({ level: 0}),
|
||||||
|
anointed: Raider({ level: 0}),
|
||||||
|
champion: Raider({ level: 0}),
|
||||||
|
profit_per_second: 0 // irrelevant for this test
|
||||||
|
});
|
||||||
|
uint256 profits_per_second = RaidGeldUtils.calculateProfitsPerSecond(army);
|
||||||
|
assertEq(profits_per_second, 1);
|
||||||
|
|
||||||
|
army = Army({
|
||||||
|
moloch_denier: Raider({ level: 2}),
|
||||||
|
apprentice: Raider({ level: 0}),
|
||||||
|
anointed: Raider({ level: 10}),
|
||||||
|
champion: Raider({ level: 1}),
|
||||||
|
profit_per_second: 0 // irrelevant for this test
|
||||||
|
});
|
||||||
|
profits_per_second = RaidGeldUtils.calculateProfitsPerSecond(army);
|
||||||
|
assertEq(profits_per_second, 640);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user