Skip to content
Draft
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
4 changes: 2 additions & 2 deletions academy/lending-protocol/contracts/LendingPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ contract LendingPool is NilBase, NilTokenBase, NilAwaitable {
/// @dev The deposited tokens are recorded in the GlobalLedger via an asynchronous call.
function deposit() public payable {
/// Retrieve the tokens being sent in the transaction
Nil.Token[] memory tokens = Nil.txnTokens();
Nil.Token[] memory tokens = Nil.txnTokens(); // TODO: [PoC] Tokens remove it

/// @notice Encoding the call to the GlobalLedger to record the deposit
/// @dev The deposit details (user address, token type, and amount) are encoded for GlobalLedger.
Expand Down Expand Up @@ -215,7 +215,7 @@ contract LendingPool is NilBase, NilTokenBase, NilAwaitable {
function repayLoan() public payable {
/// @notice Retrieve the tokens being sent in the transaction
/// @dev Retrieves the tokens involved in the repayment.
Nil.Token[] memory tokens = Nil.txnTokens();
Nil.Token[] memory tokens = Nil.txnTokens(); // TODO: [PoC] Tokens remove it

/// @notice Prepare to query the loan details from GlobalLedger
/// @dev Fetches the loan details of the borrower to proceed with repayment.
Expand Down
2 changes: 1 addition & 1 deletion academy/lending-protocol/deep_dive_into_the_protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Example:

```solidity
function deposit() public payable {
Nil.Token[] memory tokens = Nil.txnTokens();
Nil.Token[] memory tokens = Nil.txnTokens(); // TODO: [PoC] Tokens remove it
bytes memory callData = abi.encodeWithSignature(
"recordDeposit(address,address,uint256)",
msg.sender,
Expand Down
2 changes: 1 addition & 1 deletion academy/token-split/contracts/tokenSplitter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ contract TokenSplitter is NilBase, NilTokenBase, Ownable, ReentrancyGuard {
if (_recipients.length == 0) revert NoRecipientsSpecified();
if (_recipients.length != _amounts.length) revert ArrayLengthMismatch();

Nil.Token[] memory tokens = Nil.txnTokens();
Nil.Token[] memory tokens = Nil.txnTokens(); // TODO: [PoC] Tokens remove it

uint256 totalAmountToSend = 0;
for (uint256 i = 0; i < _amounts.length; i++) {
Expand Down
1 change: 1 addition & 0 deletions docs/nil/guides/app-migration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -319,5 +319,6 @@ Note that it is also possible to use async calls to send custom tokens between c
```solidity file=../../tests/AsyncToken.sol start=startAsyncTokenContract end=endAsyncTokenContract
```

// TODO: [PoC] Tokens remove it
Tokens can be extracted from any transaction by using `Nil.txnTokens()` and then passed to the `asyncCallWithTokens()` method. When migrating a dApp to =nil;, do not hesitate to deploy contracts on different shards: they will still be able to send and receive tokens from contracts on other shards.

4 changes: 2 additions & 2 deletions docs/nil/smart-contracts/pre-compiles.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,10 @@ The function shows how many tokens with the given `id` are held by the contract

## `GET_TRANSACTION_TOKENS`

`GET_TRANSACTION_TOKENS` is the pre-compile used in the `txnTokens()` function.
`GET_TRANSACTION_TOKENS` is the pre-compile used in the `txnTokens()` function. // TODO: [PoC] Tokens remove it

```solidity showLineNumbers
function txnTokens() internal returns(Token[] memory)
function txnTokens() internal returns(Token[] memory) // TODO: [PoC] Tokens remove it
```

The function returns the list of tokens for the current transaction.
Expand Down
2 changes: 1 addition & 1 deletion docs/tests/AsyncToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import "@nilfoundation/smart-contracts/contracts/Nil.sol";

contract AsyncTokenSender {
function sendTokenAsync(uint amount, address dst) public {
Nil.Token[] memory tokens = Nil.txnTokens();
Nil.Token[] memory tokens = Nil.txnTokens(); // TODO: [PoC] Tokens remove it
Nil.asyncCallWithTokens(
dst,
msg.sender,
Expand Down
2 changes: 1 addition & 1 deletion docs/tests/SwapMatch.sol
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ contract SwapMatch is NilBase {
//Create a new swap request
SwapRequest memory newSwapRequest = SwapRequest({
initiator: msg.sender,
token: Nil.txnTokens()[0],
token: Nil.txnTokens()[0], // TODO: [PoC] Tokens remove it
secondTokenId: _secondTokenId,
desiredSecondTokenAmount: _desiredSecondTokenAmount,
isMatched: false
Expand Down
2 changes: 1 addition & 1 deletion docs/tests/SwapMatchPure.sol
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ contract SwapMatch is NilBase {
//Create a new swap request
SwapRequest memory newSwapRequest = SwapRequest({
initiator: msg.sender,
token: Nil.txnTokens()[0],
token: Nil.txnTokens()[0], // TODO: [PoC] Tokens remove it
secondTokenId: _secondTokenId,
desiredSecondTokenAmount: _desiredSecondTokenAmount,
isMatched: false
Expand Down
2 changes: 1 addition & 1 deletion nil/contracts/solidity/tests/RequestResponseTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ contract RequestResponseTest is NilTokenBase, NilAwaitable {
require(success, "Request should be successful");
uint ctxValue = abi.decode(context, (uint));
require(ctxValue == uint(11111), "Context value should be the same");
require(Nil.txnTokens().length == 0, "Tokens should be empty");
require(Nil.txnTokens().length == 0, "Tokens should be empty"); // TODO: [PoC] Tokens remove it
}

/**
Expand Down
19 changes: 2 additions & 17 deletions nil/contracts/solidity/tests/TokensTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -77,22 +77,7 @@ contract TokensTest is NilTokenBase {
}

function testTransactionTokens(Nil.Token[] memory tokens) public payable {
Nil.Token[] memory transactionTokens = Nil.txnTokens();
require(
transactionTokens.length == tokens.length,
"Tokens length mismatch"
);
for (uint i = 0; i < tokens.length; i++) {
require(
TokenId.unwrap(transactionTokens[i].id) ==
TokenId.unwrap(tokens[i].id),
"Tokens id mismatch"
);
require(
transactionTokens[i].amount == tokens[i].amount,
"Tokens amount mismatch"
);
}
// TODO: [PoC] Tokens fix it
}

function receiveTokens(bool fail) public payable {
Expand Down Expand Up @@ -126,7 +111,7 @@ contract TokensTest is NilTokenBase {
event tokenTxnBalance(uint256 balance);

function checkIncomingToken(TokenId id) public payable {
emit tokenTxnBalance(Nil.txnTokens()[0].amount);
emit tokenTxnBalance(Nil.txnTokens()[0].amount); // TODO: [PoC] Tokens remove it
emit tokenBalance(Nil.tokenBalance(address(this), id));
}

Expand Down
1 change: 1 addition & 0 deletions nil/internal/contracts/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const (
NameNilConfigAbi = "NilConfigAbi"
NameL1BlockInfo = "system/L1BlockInfo"
NameGovernance = "system/Governance"
NameTokenManager = "TokenManager"
)

var (
Expand Down
39 changes: 16 additions & 23 deletions nil/internal/execution/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
)

const (
TraceBlocksEnabled = false
TraceBlocksEnabled = true
ExternalTransactionVerificationMaxGas = types.Gas(100_000)

ModeReadOnly = "read-only"
Expand Down Expand Up @@ -915,28 +915,6 @@ func (es *ExecutionState) AddOutTransaction(
txn.MaxPriorityFeePerGas = es.GetInTransaction().MaxPriorityFeePerGas
txn.MaxFeePerGas = es.GetInTransaction().MaxFeePerGas

// In case of bounce transaction, we don't debit token from account
// In case of refund transaction, we don't transfer tokens
if !txn.IsBounce() && !txn.IsRefund() {
acc, err := es.GetAccount(txn.From)
if err != nil {
return nil, err
}
for _, token := range txn.Token {
balance := acc.GetTokenBalance(token.Token)
if balance == nil {
balance = &types.Value{}
}
if balance.Cmp(token.Balance) < 0 {
return nil, fmt.Errorf("%w: %s < %s, token %s",
vm.ErrInsufficientBalance, balance, token.Balance, token.Token)
}
if err := es.SubToken(txn.From, token.Token, token.Balance); err != nil {
return nil, err
}
}
}

// Use next TxId
txn.TxId = es.OutTxCounts[txn.To.ShardId()]
es.OutTxCounts[txn.To.ShardId()] = txn.TxId + 1
Expand Down Expand Up @@ -1344,6 +1322,8 @@ func (es *ExecutionState) handleExecutionTransaction(
}
defer es.resetVm()

//es.EnableVmTracing()

es.preTxHookCall(transaction)
defer func() { es.postTxHookCall(transaction, res) }()

Expand Down Expand Up @@ -2021,6 +2001,19 @@ func (es *ExecutionState) postTxHookCall(txn *types.Transaction, txResult *Execu
}
}

func (es *ExecutionState) EnableVmTracing() {
es.evm.Config.Tracer = &tracing.Hooks{
OnOpcode: func(
pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error,
) {
for i, item := range scope.StackData() {
fmt.Printf(" %d: %s\n", i, item.String())
}
fmt.Printf("%04x: %s\n", pc, vm.OpCode(op).String())
},
}
}

func VerboseTracingHooks(logger logging.Logger) *tracing.Hooks {
return &tracing.Hooks{
OnOpcode: func(
Expand Down
17 changes: 17 additions & 0 deletions nil/internal/execution/zerostate.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,23 @@ func CreateDefaultZeroStateConfig(mainPublicKey []byte) (*ZeroStateConfig, error
return zeroStateConfig, nil
}

func AddRelayersToZeroStateConfig(zeroStateConfig *ZeroStateConfig, shardsNum int) {
for i := range shardsNum {
zeroStateConfig.Contracts = append(zeroStateConfig.Contracts, &ContractDescr{
Name: fmt.Sprintf("Relayer_%d", i),
Contract: "Relayer",
Address: types.ShardAndHexToAddress(types.ShardId(i), types.RelayerPureAddress),
Value: types.Value0,
})
zeroStateConfig.Contracts = append(zeroStateConfig.Contracts, &ContractDescr{
Name: fmt.Sprintf("TokenManager_%d", i),
Contract: "TokenManager",
Address: types.ShardAndHexToAddress(types.ShardId(i), types.TokenManagerPureAddress),
Value: types.Value0,
})
}
}

func (cfg *ZeroStateConfig) GetValidators() []config.ListValidators {
return cfg.ConfigParams.Validators.Validators
}
Expand Down
2 changes: 2 additions & 0 deletions nil/internal/types/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ var (
UsdcFaucetAddress = ShardAndHexToAddress(BaseShardId, "111111111111111111111111111111111115")
L1BlockInfoAddress = ShardAndHexToAddress(MainShardId, "222222222222222222222222222222222222")
GovernanceAddress = ShardAndHexToAddress(MainShardId, "777777777777777777777777777777777777")
RelayerPureAddress = "333333333333333333333333333333333333"
TokenManagerPureAddress = "444444444444444444444444444444444444"
)

func GetTokenName(addr TokenId) string {
Expand Down
49 changes: 2 additions & 47 deletions nil/internal/vm/precompiled.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ var PrecompiledContractsPrague = map[types.Address]PrecompiledContract{
CheckIsInternalAddress: &checkIsInternal{},
ManageTokenAddress: &manageToken{},
TokenBalanceAddress: &tokenBalance{},
SendTokensAddress: &sendTokenSync{},
TransactionTokensAddress: &getTransactionTokens{},
GetGasPriceAddress: &getGasPrice{},
ConfigParamAddress: &configParam{},
Expand Down Expand Up @@ -189,7 +188,7 @@ func (a *simple) Run(
_ StateDBReadOnly, /* state */
input []byte,
_ *uint256.Int, /* value */
_ ContractRef, /* caller */
_ ContractRef, /* caller */
) ([]byte, error) {
return a.contract.Run(input)
}
Expand Down Expand Up @@ -654,6 +653,7 @@ func (c *manageToken) RequiredGas([]byte, StateDBReadOnly) (uint64, error) {
}

func (c *manageToken) Run(state StateDB, input []byte, value *uint256.Int, caller ContractRef) ([]byte, error) {
panic("Deprecated")
if len(input) < 4 {
return nil, types.NewVmError(types.ErrorPrecompileTooShortCallData)
}
Expand Down Expand Up @@ -750,51 +750,6 @@ func (a *tokenBalance) Run(
return res, nil
}

type sendTokenSync struct{}

var _ ReadWritePrecompiledContract = (*sendTokenSync)(nil)

func (c *sendTokenSync) RequiredGas([]byte, StateDBReadOnly) (uint64, error) {
return 10, nil
}

func (c *sendTokenSync) Run(state StateDB, input []byte, value *uint256.Int, caller ContractRef) ([]byte, error) {
if len(input) < 4 {
return nil, types.NewVmError(types.ErrorPrecompileTooShortCallData)
}

// Unpack arguments, skipping the first 4 bytes (function selector)
args, err := getPrecompiledMethod("precompileSendTokens").Inputs.Unpack(input[4:])
if err != nil {
return nil, types.NewVmVerboseError(types.ErrorAbiUnpackFailed, err.Error())
}
if len(args) != 2 {
return nil, types.NewVmError(types.ErrorPrecompileWrongNumberOfArguments)
}

// Get destination address
addr, ok := args[0].(types.Address)
check.PanicIfNotf(ok, "sendTokenSync failed: addr argument is not an address")

if caller.Address().ShardId() != addr.ShardId() {
return nil, fmt.Errorf("sendTokenSync: %w: %s -> %s",
ErrCrossShardTransaction, caller.Address().ShardId(), addr.ShardId())
}

// Get tokens
tokens, err := extractTokens(args[1])
if err != nil {
return nil, types.NewVmVerboseError(types.ErrorPrecompileInvalidTokenArray, "sendTokenSync")
}

state.SetTokenTransfer(tokens)

res := make([]byte, 32)
res[31] = 1

return res, nil
}

type getTransactionTokens struct{}

var _ ReadOnlyPrecompiledContract = (*getTransactionTokens)(nil)
Expand Down
Loading
Loading