aboutsummaryrefslogtreecommitdiff
path: root/contracts/arc20.sol
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/arc20.sol
parent2d0a37c6490dc9a4ec36ee4ebbed01c790f0426a (diff)
Add native asset precompiled contracts for apricot release
Diffstat (limited to 'contracts/arc20.sol')
-rw-r--r--contracts/arc20.sol150
1 files changed, 150 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];
+ }
+}