diff --git a/backend/Shifting/README.md b/backend/Shifting/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..f8b7f7ef408a97c3869986c56fa83c1772a2bdc8
--- /dev/null
+++ b/backend/Shifting/README.md
@@ -0,0 +1,6 @@
+# Shifting contracts
+
+- chainlink-oracle.sol: chainlink price feed contract
+- shift-contract.sol: shifting contract 
+- shift-with-faucet: shifting contract plus xftT faucet
+- testnet-tokens, xftTest-asset.sol: testnet erc20 tokens
\ No newline at end of file
diff --git a/backend/Shifting/testnet-tokens.sol b/backend/Shifting/testnet-tokens.sol
new file mode 100644
index 0000000000000000000000000000000000000000..47f22c6f07bd4acf863b1cf9c03e93212cd43329
--- /dev/null
+++ b/backend/Shifting/testnet-tokens.sol
@@ -0,0 +1,83 @@
+// contracts/zkAsset.sol
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.6.0;
+
+import "../localhost/@openzeppelin/contracts/access/AccessControl.sol";
+import "../localhost/@openzeppelin/contracts/GSN/Context.sol";
+import "../localhost/@openzeppelin/contracts/token/ERC20/ERC20.sol";
+import "../localhost/@openzeppelin/contracts/token/ERC20/ERC20Burnable.sol";
+import "../localhost/@openzeppelin/contracts/token/ERC20/ERC20Pausable.sol";
+
+contract zkAsset is ERC20, AccessControl, ERC20Burnable, ERC20Pausable {
+    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
+    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
+    bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
+
+    constructor() public ERC20("zkTEST-Asset", "zkA") {
+
+        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
+        _setupRole(MINTER_ROLE, msg.sender);
+        _setupRole(BURNER_ROLE, msg.sender);
+        _setupRole(PAUSER_ROLE, msg.sender);
+    }
+
+    /**
+    * @dev Destroys `amount` tokens for `from`.
+    *
+    * See {ERC20-_burn}.
+    *
+    * Requirements:
+    *
+    * - the caller must have the `BURNER_ROLE`.
+    */
+    function burn(address from, uint256 amount) public {
+        require(hasRole(BURNER_ROLE, msg.sender), "zkAsset: must have burner role to burn");
+        _burn(from, amount);
+    }
+
+    /**
+     * @dev Creates `amount` new tokens for `to`.
+     *
+     * See {ERC20-_mint}.
+     *
+     * Requirements:
+     *
+     * - the caller must have the `MINTER_ROLE`.
+     */
+    function mint(address to, uint256 amount) public {
+        require(hasRole(MINTER_ROLE, _msgSender()), "zkAsset: must have minter role to mint");
+        _mint(to, amount);
+    }
+
+    /**
+     * @dev Pauses all token transfers.
+     *
+     * See {ERC20Pausable} and {Pausable-_pause}.
+     *
+     * Requirements:
+     *
+     * - the caller must have the `PAUSER_ROLE`.
+     */
+    function pause() public {
+        require(hasRole(PAUSER_ROLE, _msgSender()), "zkAsset: must have pauser role to pause");
+        _pause();
+    }
+
+    /**
+     * @dev Unpauses all token transfers.
+     *
+     * See {ERC20Pausable} and {Pausable-_unpause}.
+     *
+     * Requirements:
+     *
+     * - the caller must have the `PAUSER_ROLE`.
+     */
+    function unpause() public {
+        require(hasRole(PAUSER_ROLE, _msgSender()), "zkAsset: must have pauser role to unpause");
+        _unpause();
+    }
+
+    function _beforeTokenTransfer(address from, address to, uint256 amount) internal override(ERC20, ERC20Pausable) {
+        super._beforeTokenTransfer(from, to, amount);
+    }
+}
diff --git a/backend/Shifting/xftTest-asset.sol b/backend/Shifting/xftTest-asset.sol
new file mode 100644
index 0000000000000000000000000000000000000000..0c949671c645b707408adb14b1b9c9aad47d0291
--- /dev/null
+++ b/backend/Shifting/xftTest-asset.sol
@@ -0,0 +1,83 @@
+// contracts/zkAsset.sol
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.6.0;
+
+import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/AccessControl.sol";
+import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/GSN/Context.sol";
+import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol";
+import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20Pausable.sol";
+import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20Burnable.sol";
+
+contract zkAasset is ERC20, AccessControl, ERC20Burnable, ERC20Pausable {
+    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
+    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
+    bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
+
+    constructor() public ERC20("xftTEST-Asset", "xftT") {
+
+        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
+        _setupRole(MINTER_ROLE, msg.sender);
+        _setupRole(BURNER_ROLE, msg.sender);
+        _setupRole(PAUSER_ROLE, msg.sender);
+    }
+
+    /**
+    * @dev Destroys `amount` tokens for `from`.
+    *
+    * See {ERC20-_burn}.
+    *
+    * Requirements:
+    *
+    * - the caller must have the `BURNER_ROLE`.
+    */
+    function burn(address from, uint256 amount) public {
+        require(hasRole(BURNER_ROLE, msg.sender), "xftTEST-Asset: must have burner role to burn");
+        _burn(from, amount);
+    }
+
+    /**
+     * @dev Creates `amount` new tokens for `to`.
+     *
+     * See {ERC20-_mint}.
+     *
+     * Requirements:
+     *
+     * - the caller must have the `MINTER_ROLE`.
+     */
+    function mint(address to, uint256 amount) public {
+        require(hasRole(MINTER_ROLE, _msgSender()), "xftTEST-Asset: must have minter role to mint");
+        _mint(to, amount);
+    }
+
+    /**
+     * @dev Pauses all token transfers.
+     *
+     * See {ERC20Pausable} and {Pausable-_pause}.
+     *
+     * Requirements:
+     *
+     * - the caller must have the `PAUSER_ROLE`.
+     */
+    function pause() public {
+        require(hasRole(PAUSER_ROLE, _msgSender()), "xftTEST-Asset: must have pauser role to pause");
+        _pause();
+    }
+
+    /**
+     * @dev Unpauses all token transfers.
+     *
+     * See {ERC20Pausable} and {Pausable-_unpause}.
+     *
+     * Requirements:
+     *
+     * - the caller must have the `PAUSER_ROLE`.
+     */
+    function unpause() public {
+        require(hasRole(PAUSER_ROLE, _msgSender()), "xftTEST-Asset: must have pauser role to unpause");
+        _unpause();
+    }
+
+    function _beforeTokenTransfer(address from, address to, uint256 amount) internal override(ERC20, ERC20Pausable) {
+        super._beforeTokenTransfer(from, to, amount);
+    }
+}