aboutsummaryrefslogtreecommitdiff
path: root/contracts
diff options
context:
space:
mode:
authorAaron Buchwald <[email protected]>2020-11-23 20:46:35 -0500
committerAaron Buchwald <[email protected]>2020-12-15 10:46:26 -0500
commit368844ad2a28ec07848e3c0169cf2b83b579a2e8 (patch)
tree0b3956351add28aed944824eb45ffb2723809dba /contracts
parent2d0a37c6490dc9a4ec36ee4ebbed01c790f0426a (diff)
Add native asset precompiled contracts for apricot release
Diffstat (limited to 'contracts')
-rw-r--r--contracts/arc20.sol150
-rw-r--r--contracts/nativeAssets.sol20
2 files changed, 170 insertions, 0 deletions
diff --git a/contracts/arc20.sol b/contracts/arc20.sol
new file mode 100644
index 0000000..a7fc997
--- /dev/null
+++ b/contracts/arc20.sol
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity >=0.6.0 <0.8.0;
+
+import {NativeAssets} from "./NativeAssets.sol";
+
+contract ARC20 {
+
+ mapping (address => uint256) private _balances;
+ mapping(address => mapping(address => uint256)) private _allowances;
+
+ uint256 private _assetID;
+
+ uint256 private _totalSupply;
+
+ string private _name;
+ string private _symbol;
+ uint8 private _decimals;
+
+ constructor(string memory name_, string memory symbol_, uint8 decimals_, uint256 assetID_) public {
+ _name = name_;
+ _symbol = symbol_;
+ _decimals = decimals_;
+ _assetID = assetID_;
+ }
+
+ /**
+ * @dev Returns the name of the token.
+ */
+ function name() public view returns (string memory) {
+ return _name;
+ }
+
+ /**
+ * @dev Returns the symbol of the token, usually a shorter version of the
+ * name.
+ */
+ function symbol() public view returns (string memory) {
+ return _symbol;
+ }
+
+ /**
+ * @dev Returns the number of decimals used to represent the token.
+ */
+ function decimals() public view returns (uint8) {
+ return _decimals;
+ }
+
+ /**
+ * @dev Returns the total supply of `assetID` currently held by
+ * this contract.
+ */
+ function totalSupply() public view returns (uint256) {
+ return _totalSupply;
+ }
+
+ /**
+ * @dev Returns the balance of `account` held in this contract.
+ */
+ function balanceOf(address account) public view returns (uint256) {
+ return _balances[account];
+ }
+
+ // Withdrawal/Deposit functionality
+
+ /**
+ * @dev Acknowledges the receipt of some amount of an Avalanche Native Token
+ * into the contract implementing this interface.
+ */
+ function deposit() public {
+ uint256 updatedBalance = NativeAssets.assetBalance(address(this), _assetID);
+ uint256 depositAmount = updatedBalance - _totalSupply;
+ assert(depositAmount >= 0);
+
+ _balances[msg.sender] += depositAmount;
+ _totalSupply = updatedBalance;
+ emit Deposit(msg.sender, depositAmount);
+ }
+
+ /**
+ * @dev Emitted when `value` tokens are deposited from `depositor`
+ */
+ event Deposit(address indexed depositor, uint256 value);
+
+ /**
+ * @dev Withdraws `value` of the underlying asset to the contract
+ * caller.
+ */
+ function withdraw(uint256 value) public {
+ require(_balances[msg.sender] >= value, "Insufficient funds for withdrawal");
+
+ _balances[msg.sender] -= value;
+ _totalSupply -= value;
+
+ NativeAssets.assetCall(msg.sender, _assetID, value, "");
+ emit Withdrawal(msg.sender, value);
+ }
+
+ /**
+ * @dev Emitted when `value` tokens are withdrawn to `withdrawer`
+ */
+ event Withdrawal(address indexed withdrawer, uint256 value);
+
+ /**
+ * @dev Returns the `assetID` of the underlying asset this contract handles.
+ */
+ function assetID() external view returns (uint256) {
+ return _assetID;
+ }
+
+ event Transfer(address indexed from, address indexed to, uint256 value);
+
+ function transfer(address to, uint256 value) public returns (bool success) {
+ require(_balances[msg.sender] >= value, "insufficient balance for transfer");
+
+ _balances[msg.sender] -= value; // deduct from sender's balance
+ _balances[to] += value; // add to recipient's balance
+ emit Transfer(msg.sender, to, value);
+ return true;
+ }
+
+ event Approval(address indexed owner, address indexed spender, uint256 value);
+
+ function approve(address spender, uint256 value)
+ public
+ returns (bool success)
+ {
+ _allowances[msg.sender][spender] = value;
+ emit Approval(msg.sender, spender, value);
+ return true;
+ }
+
+ function transferFrom(address from, address to, uint256 value)
+ public
+ returns (bool success)
+ {
+ require(value <= _balances[from], "From address has insufficient balance to transfer");
+ require(value <= _allowances[from][msg.sender], "Insufficient allowance granted to sender");
+
+ _balances[from] -= value;
+ _balances[to] += value;
+ _allowances[from][msg.sender] -= value;
+ emit Transfer(from, to, value);
+ return true;
+ }
+
+ function allowance(address owner, address spender) public view returns (uint256) {
+ return _allowances[owner][spender];
+ }
+}
diff --git a/contracts/nativeAssets.sol b/contracts/nativeAssets.sol
new file mode 100644
index 0000000..0656271
--- /dev/null
+++ b/contracts/nativeAssets.sol
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity >=0.6.0 <0.8.0;
+
+library NativeAssets {
+ address constant balanceAddr = 0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF;
+ address constant transferAddr = 0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE;
+
+ function assetBalance(address addr, uint256 assetID) public returns (uint256) {
+ (bool success, bytes memory data) = balanceAddr.call(abi.encodePacked(addr, assetID));
+ require(success, "assetBalance failed");
+ return abi.decode(data, (uint256));
+ }
+
+ function assetCall(address addr, uint256 assetID, uint256 assetAmount, bytes memory callData) public returns (bytes memory) {
+ (bool success, bytes memory data) = transferAddr.call(abi.encodePacked(addr, assetID, assetAmount, callData));
+ require(success, "assetCall failed");
+ return data;
+ }
+}