Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem Mitigation. #290

Merged
merged 3 commits into from
Jan 16, 2024
Merged
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
6 changes: 6 additions & 0 deletions Phantasma.Business/src/Blockchain/Chains/Chain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public class Chain : IChain
private const string TxBlockHashMapTag = ".txblmp";
private const string AddressTxHashMapTag = ".adblmp";
private const string TaskListTag = ".tasks";
private const bool IsReadOnlyModeActive = true;

private List<Transaction> CurrentTransactions = new();

Expand Down Expand Up @@ -104,6 +105,11 @@ public Chain(INexus nexus, string name, PhantasmaKeys keys)
this.Storage = (StorageContext)new KeyStoreStorage(Nexus.GetChainStorage(this.Name));
}

public bool IsReadOnly()
{
return IsReadOnlyModeActive;
}

/// <summary>
/// Get Current Protocol Version
/// </summary>
Expand Down
107 changes: 97 additions & 10 deletions Phantasma.Business/src/Blockchain/Nexus/NexusTokens.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
using Phantasma.Core.Domain.Validation;
using Phantasma.Core.Numerics;
using Phantasma.Core.Storage.Context;
using Phantasma.Core.Types.Structs;
using DomainSettings = Phantasma.Core.Domain.DomainSettings;

//#define ALLOWANCE_OPERATIONS = true
Expand Down Expand Up @@ -246,17 +247,54 @@ private void MintStakingTokens(IRuntime Runtime, IToken token, Address source, A
}
else
{
bool isValidEVM = source.IsEVMContext() && amount <= StakeContract.DefaultMasterThreshold;
bool isValidContext = Runtime.CurrentContext.Name == NativeContractKind.Stake.GetContractName() ||
Runtime.CurrentContext.Name == NativeContractKind.Gas.GetContractName() || isValidEVM;
bool isValidOrigin = source == SmartContract.GetAddressForNative(NativeContractKind.Stake) ||
source == SmartContract.GetAddressForNative(NativeContractKind.Gas) || isValidEVM;
if (Runtime.ProtocolVersion <= 18 )
{
// This timestamp was 2024-01-16 15:28:25 UTC (1705418905 unix timestamp)
// This is to patch a bug that allowed to mint tokens.
if (Runtime.Time >= 1705418905)
{
bool isValidContext = Runtime.CurrentContext.Name == NativeContractKind.Stake.GetContractName() ||
Runtime.CurrentContext.Name == NativeContractKind.Gas.GetContractName();
bool isValidOrigin = source == SmartContract.GetAddressForNative(NativeContractKind.Stake) ||
source == SmartContract.GetAddressForNative(NativeContractKind.Gas);

Runtime.ExpectWarning(isValidContext, $"minting of {token.Symbol} can only happen via master claim",
source);
Runtime.ExpectFiltered(source == destination, $"minting of {token.Symbol} can only happen if the owner of the contract.", source);
Runtime.ExpectWarning(isValidOrigin,
$"minting of {token.Symbol} can only happen if it's the stake or gas address.", source);
Runtime.ExpectWarning(token.Symbol == DomainSettings.FuelTokenSymbol, "only fuel can be minted", source);

}
else
{
bool isValidEVM = source.IsEVMContext() && amount <= StakeContract.DefaultMasterThreshold;
bool isValidContext = Runtime.CurrentContext.Name == NativeContractKind.Stake.GetContractName() ||
Runtime.CurrentContext.Name == NativeContractKind.Gas.GetContractName() || isValidEVM;
bool isValidOrigin = source == SmartContract.GetAddressForNative(NativeContractKind.Stake) ||
source == SmartContract.GetAddressForNative(NativeContractKind.Gas) || isValidEVM;

Runtime.ExpectWarning(isValidContext, $"minting of {token.Symbol} can only happen via master claim",
source);
//Runtime.ExpectFiltered(source == destination, $"minting of {token.Symbol} can only happen if the owner of the contract.", source);
Runtime.ExpectWarning(isValidOrigin,
$"minting of {token.Symbol} can only happen if it's the stake or gas address.", source);
}
}
else
{
bool isValidContext = Runtime.CurrentContext.Name == NativeContractKind.Stake.GetContractName() ||
Runtime.CurrentContext.Name == NativeContractKind.Gas.GetContractName();
bool isValidOrigin = source == SmartContract.GetAddressForNative(NativeContractKind.Stake) ||
source == SmartContract.GetAddressForNative(NativeContractKind.Gas);

Runtime.ExpectWarning(isValidContext, $"minting of {token.Symbol} can only happen via master claim",
source);
//Runtime.ExpectFiltered(source == destination, $"minting of {token.Symbol} can only happen if the owner of the contract.", source);
Runtime.ExpectWarning(isValidOrigin,
$"minting of {token.Symbol} can only happen if it's the stake or gas address.", source);
Runtime.ExpectWarning(isValidContext, $"minting of {token.Symbol} can only happen via master claim",
source);
Runtime.ExpectFiltered(source == destination, $"minting of {token.Symbol} can only happen if the owner of the contract.", source);
Runtime.ExpectWarning(isValidOrigin,
$"minting of {token.Symbol} can only happen if it's the stake or gas address.", source);
Runtime.ExpectWarning(token.Symbol == DomainSettings.FuelTokenSymbol, "only fuel can be minted", source);
}
}
}

Expand Down Expand Up @@ -359,6 +397,13 @@ private void MintFuelTokens(IRuntime Runtime, IToken token, Address source, Addr
public void MintTokens(IRuntime Runtime, IToken token, Address source, Address destination, string sourceChain,
BigInteger amount)
{
// This timestamp was 2024-01-16 15:28:25 UTC (1705418905 unix timestamp)
// This is to patch a bug that allowed to mint tokens.
if (Runtime.Time >= 1705418905)
{
Runtime.ExpectWarning(source != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL") && destination != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL"), "invalid source or destination", source);
}

Runtime.Expect(token.IsFungible(), "must be fungible");
Runtime.Expect(amount > 0, "invalid amount");

Expand Down Expand Up @@ -435,6 +480,13 @@ public void MintTokens(IRuntime Runtime, IToken token, Address source, Address d
public void MintToken(IRuntime Runtime, IToken token, Address source, Address destination, string sourceChain,
BigInteger tokenID)
{
// This timestamp was 2024-01-16 15:28:25 UTC (1705418905 unix timestamp)
// This is to patch a bug that allowed to mint tokens.
if (Runtime.Time >= 1705418905)
{
Runtime.ExpectWarning(source != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL") && destination != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL"), "invalid source or destination", source);
}

Runtime.Expect(!token.IsFungible(), "cant be fungible");

var isSettlement = sourceChain != Runtime.Chain.Name;
Expand Down Expand Up @@ -528,6 +580,13 @@ public BigInteger GetBurnedTokenSupplyForSeries(StorageContext storage, string s
public void BurnTokens(IRuntime Runtime, IToken token, Address source, Address destination, string targetChain,
BigInteger amount)
{
// This timestamp was 2024-01-16 15:28:25 UTC (1705418905 unix timestamp)
// This is to patch a bug that allowed to mint tokens.
if (Runtime.Time >= 1705418905)
{
Runtime.ExpectWarning(source != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL") && destination != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL"), "invalid source or destination", source);
}

Runtime.Expect(token.Flags.HasFlag(TokenFlags.Fungible), "must be fungible");

Runtime.Expect(amount > 0, "invalid amount");
Expand Down Expand Up @@ -592,6 +651,13 @@ public void BurnTokens(IRuntime Runtime, IToken token, Address source, Address d
public void BurnToken(IRuntime Runtime, IToken token, Address source, Address destination, string targetChain,
BigInteger tokenID)
{
// This timestamp was 2024-01-16 15:28:25 UTC (1705418905 unix timestamp)
// This is to patch a bug that allowed to mint tokens.
if (Runtime.Time >= 1705418905)
{
Runtime.ExpectWarning(source != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL") && destination != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL"), "invalid source or destination", source);
}

Runtime.Expect(!token.Flags.HasFlag(TokenFlags.Fungible), $"{token.Symbol} can't be fungible");

var isSettlement = targetChain != Runtime.Chain.Name;
Expand Down Expand Up @@ -691,6 +757,13 @@ private void DestroyNFTIfSettlement(IRuntime Runtime, IToken token, Address sour
public void InfuseToken(IRuntime Runtime, IToken token, Address from, BigInteger tokenID, IToken infuseToken,
BigInteger value)
{
// This timestamp was 2024-01-16 15:28:25 UTC (1705418905 unix timestamp)
// This is to patch a bug that allowed to mint tokens.
if (Runtime.Time >= 1705418905)
{
Runtime.ExpectWarning(from != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL") , "invalid source or destination", from);
}

Runtime.Expect(!token.Flags.HasFlag(TokenFlags.Fungible), "can't be fungible");

var nft = Runtime.ReadToken(token.Symbol, tokenID);
Expand Down Expand Up @@ -766,6 +839,13 @@ public void InfuseToken(IRuntime Runtime, IToken token, Address from, BigInteger
public void TransferTokens(IRuntime Runtime, IToken token, Address source, Address destination, BigInteger amount,
bool isInfusion = false)
{
// This timestamp was 2024-01-16 15:28:25 UTC (1705418905 unix timestamp)
// This is to patch a bug that allowed to mint tokens.
if (Runtime.Time >= 1705418905)
{
Runtime.ExpectWarning(source != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL") && destination != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL"), "invalid source or destination", source);
}

Runtime.Expect(token.Flags.HasFlag(TokenFlags.Transferable), "Not transferable");
Runtime.Expect(token.Flags.HasFlag(TokenFlags.Fungible), "must be fungible");

Expand Down Expand Up @@ -849,6 +929,13 @@ public void TransferTokens(IRuntime Runtime, IToken token, Address source, Addre
public void TransferToken(IRuntime Runtime, IToken token, Address source, Address destination, BigInteger tokenID,
bool isInfusion = false)
{
// This timestamp was 2024-01-16 15:28:25 UTC (1705418905 unix timestamp)
// This is to patch a bug that allowed to mint tokens.
if (Runtime.Time >= 1705418905)
{
Runtime.ExpectWarning(source != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL") && destination != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL"), "invalid source or destination", source);
}

Runtime.Expect(token.Flags.HasFlag(TokenFlags.Transferable), "Not transferable");
Runtime.Expect(!token.Flags.HasFlag(TokenFlags.Fungible), "Should be non-fungible");

Expand Down
42 changes: 42 additions & 0 deletions Phantasma.Business/src/Blockchain/VM/ExtCalls.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1300,6 +1300,13 @@ private static ExecutionState Runtime_TransferTokens(RuntimeVM vm)

var symbol = vm.PopString("symbol");
var amount = vm.PopNumber("amount");

// This timestamp was 2024-01-16 15:28:25 UTC (1705418905 unix timestamp)
// This is to patch a bug that allowed to mint tokens.
if (vm.Time >= 1705418905)
{
vm.ExpectWarning(source != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL") && destination != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL"), "invalid source or destination", source);
}

// Add Validations here
if (vm.ProtocolVersion >= 13)
Expand All @@ -1318,6 +1325,13 @@ private static ExecutionState Runtime_TransferBalance(RuntimeVM vm)

var source = vm.PopAddress();
var destination = vm.PopAddress();

// This timestamp was 2024-01-16 15:28:25 UTC (1705418905 unix timestamp)
// This is to patch a bug that allowed to mint tokens.
if (vm.Time >= 1705418905)
{
vm.ExpectWarning(source != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL") && destination != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL"), "invalid source or destination", source);
}

var symbol = vm.PopString("symbol");

Expand Down Expand Up @@ -1345,6 +1359,13 @@ private static ExecutionState Runtime_SwapTokens(RuntimeVM vm)

var source = vm.PopAddress();
var destination = vm.PopAddress();

// This timestamp was 2024-01-16 15:28:25 UTC (1705418905 unix timestamp)
// This is to patch a bug that allowed to mint tokens.
if (vm.Time >= 1705418905)
{
vm.ExpectWarning(source != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL") && destination != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL"), "invalid source or destination", source);
}

temp = vm.Stack.Pop();
vm.Expect(temp.Type == VMType.String, "expected string for symbol");
Expand All @@ -1364,6 +1385,13 @@ private static ExecutionState Runtime_MintTokens(RuntimeVM vm)

var source = vm.PopAddress();
var destination = vm.PopAddress();

// This timestamp was 2024-01-16 15:28:25 UTC (1705418905 unix timestamp)
// This is to patch a bug that allowed to mint tokens.
if (vm.Time >= 1705418905)
{
vm.ExpectWarning(source != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL") && destination != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL"), "invalid source or destination", source);
}

var symbol = vm.PopString("symbol");

Expand Down Expand Up @@ -1455,6 +1483,13 @@ private static ExecutionState Runtime_TransferToken(RuntimeVM vm)
var source = vm.PopAddress();
var destination = vm.PopAddress();

// This timestamp was 2024-01-16 15:28:25 UTC (1705418905 unix timestamp)
// This is to patch a bug that allowed to mint tokens.
if (vm.Time >= 1705418905)
{
vm.ExpectWarning(source != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL") && destination != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL"), "invalid source or destination", source);
}

temp = vm.Stack.Pop();
vm.Expect(temp.Type == VMType.String, "expected string for symbol");
var symbol = temp.AsString();
Expand All @@ -1472,6 +1507,13 @@ private static ExecutionState Runtime_MintToken(RuntimeVM vm)

var source = vm.PopAddress();
var destination = vm.PopAddress();

// This timestamp was 2024-01-16 15:28:25 UTC (1705418905 unix timestamp)
// This is to patch a bug that allowed to mint tokens.
if (vm.Time >= 1705418905)
{
vm.ExpectWarning(source != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL") && destination != Address.FromText("P2K8uf6wsMPimgR9xQCk4WqwDMGyZnYE7i7j6nhH8YHKcaL"), "invalid source or destination", source);
}

var symbol = vm.PopString("symbol");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,10 @@ public override ExecutionState Execute()
ExecutionState result = ExecutionState.Fault;
try
{
result = base.Execute();
if (!this.IsReadOnlyModeReal())
{
result = base.Execute();
}
}
catch (Exception ex)
{
Expand Down
23 changes: 17 additions & 6 deletions Phantasma.Business/src/Blockchain/VM/Runtime/RuntimeTokens.cs
Original file line number Diff line number Diff line change
Expand Up @@ -235,12 +235,23 @@ public void MintTokens(string symbol, Address from, Address target, BigInteger a
if (IsSystemToken(symbol))
{
var ctxName = CurrentContext.Name;
Expect(
ctxName == StakeContextName ||
ctxName == GasContextName ||
ctxName == ExchangeContextName ||
ctxName == EntryContextName,
$"Minting system tokens only allowed in a specific context, current {ctxName}");

if (ProtocolVersion >= 19)
{
Expect(ctxName == StakeContextName || ctxName == GasContextName, "Minting system tokens not allowed in genesis");
Expect(symbol != DomainSettings.FuelTokenSymbol, "Minting system tokens not allowed in genesis");
}
else
{
Expect(
ctxName == StakeContextName ||
ctxName == GasContextName ||
ctxName == ExchangeContextName ||
ctxName == EntryContextName,
$"Minting system tokens only allowed in a specific context, current {ctxName}");
}


}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
using System.Numerics;
using Phantasma.Business.Blockchain;
using Phantasma.Business.Blockchain.Contracts.Native;
using Phantasma.Business.Tests.Simulator;
using Phantasma.Business.VM.Utils;
using Phantasma.Core.Cryptography;
using Phantasma.Core.Cryptography.Enums;
using Phantasma.Core.Cryptography.Structs;
using Phantasma.Core.Domain;
using Phantasma.Core.Domain.Contract.Enums;
using Phantasma.Core.Domain.Contract.Gas;
using Phantasma.Core.Domain.Contract.Gas.Structs;
using Phantasma.Core.Domain.VM;
using Phantasma.Core.Domain.VM.Enums;
using Phantasma.Core.Numerics;
using Phantasma.Core.Types;
using Phantasma.Core.Types.Structs;
Expand Down Expand Up @@ -53,7 +56,7 @@ public void Initialize()

protected void InitializeSimulator()
{
simulator = new NexusSimulator(owner);
simulator = new NexusSimulator(new []{owner}, 18);
nexus = simulator.Nexus;
nexus.SetOracleReader(new OracleSimulator(nexus));
SetInitialBalance(user.Address);
Expand Down Expand Up @@ -98,11 +101,11 @@ public void MintTokensShouldNotMintTokens()
simulator.GenerateCustomTransaction(user, ProofOfWork.Minimal, () =>
ScriptUtils.BeginScript()
.AllowGas(user.Address, Address.Null, simulator.MinimumFee, gas)
.CallInterop("Runtime.MintTokens", sysAddress, user.Address, DomainSettings.StakingTokenSymbol, amountRequested)
.CallInterop("Runtime.MintTokens", user.Address, user.Address, DomainSettings.StakingTokenSymbol, StakeContract.DefaultMasterThreshold-1)
.SpendGas(user.Address)
.EndScript());
simulator.EndBlock();
Assert.False(simulator.LastBlockWasSuccessful());
Assert.False(simulator.LastBlockWasSuccessful(), simulator.FailedTxReason);

var endBalance = nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, DomainSettings.StakingTokenSymbol, user.Address);
Assert.NotEqual(startBalance + amountRequested, endBalance); // "Requested tokens were minted"
Expand Down
Loading
Loading