diff --git a/.gitmodules b/.gitmodules index 888d42d..c90cdcb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,9 @@ [submodule "lib/forge-std"] path = lib/forge-std url = https://github.com/foundry-rs/forge-std +[submodule "lib/openzeppelin-contracts"] + path = lib/openzeppelin-contracts + url = https://github.com/openzeppelin/openzeppelin-contracts +[submodule "lib/openzeppelin-contracts-upgradeable"] + path = lib/openzeppelin-contracts-upgradeable + url = https://github.com/openzeppelin/openzeppelin-contracts-upgradeable diff --git a/lib/openzeppelin-contracts b/lib/openzeppelin-contracts new file mode 160000 index 0000000..69c8def --- /dev/null +++ b/lib/openzeppelin-contracts @@ -0,0 +1 @@ +Subproject commit 69c8def5f222ff96f2b5beff05dfba996368aa79 diff --git a/lib/openzeppelin-contracts-upgradeable b/lib/openzeppelin-contracts-upgradeable new file mode 160000 index 0000000..fa52531 --- /dev/null +++ b/lib/openzeppelin-contracts-upgradeable @@ -0,0 +1 @@ +Subproject commit fa525310e45f91eb20a6d3baa2644be8e0adba31 diff --git a/script/Counter.s.sol b/script/Counter.s.sol deleted file mode 100644 index cdc1fe9..0000000 --- a/script/Counter.s.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -import {Script, console} from "forge-std/Script.sol"; -import {Counter} from "../src/Counter.sol"; - -contract CounterScript is Script { - Counter public counter; - - function setUp() public {} - - function run() public { - vm.startBroadcast(); - - counter = new Counter(); - - vm.stopBroadcast(); - } -} diff --git a/script/Main.s.sol b/script/Main.s.sol new file mode 100644 index 0000000..4fdc224 --- /dev/null +++ b/script/Main.s.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {Script, console} from "forge-std/Script.sol"; +import {DepositV1} from "../src/DepositV1.sol"; +import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; + +function deployDepositV1(address move, address owner, address bridge) returns (DepositV1) { + DepositV1 implementation = new DepositV1(); + TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(address(implementation), address(owner), ""); + DepositV1 proxyContract = DepositV1(address(proxy)); + + proxyContract.initialize(move, owner, bridge); + return proxyContract; +} + +contract CounterScript is Script { + + function setUp() public {} + + function run() public { + vm.startBroadcast(); + + + vm.stopBroadcast(); + } +} diff --git a/src/Counter.sol b/src/Counter.sol deleted file mode 100644 index aded799..0000000 --- a/src/Counter.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -contract Counter { - uint256 public number; - - function setNumber(uint256 newNumber) public { - number = newNumber; - } - - function increment() public { - number++; - } -} diff --git a/src/DepositV1.sol b/src/DepositV1.sol new file mode 100644 index 0000000..5026e97 --- /dev/null +++ b/src/DepositV1.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; +import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "src/mock/NativeBridge.sol"; + +contract DepositV1 is Initializable, OwnableUpgradeable { + + + mapping(address => uint256) public deposits; + mapping(address => bytes32) public moveAddresses; + + IERC20 public move; + NativeBridge public bridge; + + event Deposit(address user, uint256 indexed amount, bytes32 indexed moveAddress, uint256 indexed timestamp); + + function initialize(address move_, address owner_, address bridge_) public initializer { + __Ownable_init(owner_); + move = IERC20(move_); + bridge = NativeBridge(bridge_); + } + + function deposit(address to, uint256 amount, bytes32 moveAddress) external { + move.transferFrom(msg.sender, address(this), amount); + deposits[to] += amount; + moveAddresses[to] = moveAddress; + + emit Deposit(to, amount, moveAddress, block.timestamp); + } + + function bridgeToMovement(bytes32 moveAddress, uint256 amount) external onlyOwner { + move.approve(address(bridge), amount); + bridge.initiateBridgeTransfer(moveAddress, amount); + + + + } +} + \ No newline at end of file diff --git a/src/mock/NativeBridge.sol b/src/mock/NativeBridge.sol new file mode 100644 index 0000000..d363a93 --- /dev/null +++ b/src/mock/NativeBridge.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.22; +pragma abicoder v2; + +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +// import {RateLimiter} from "./RateLimiter.sol"; + +contract NativeBridge { + IERC20 public moveToken; + // Prevents initialization of implementation contract exploits + constructor(address _moveToken) { + moveToken = IERC20(_moveToken); + } + + event BridgeTransferInitiated( + bytes32 indexed bridgeTransferId, + address indexed originator, + bytes32 indexed recipient, + uint256 amount, + uint256 nonce + ); + + function initiateBridgeTransfer(bytes32 recipient, uint256 amount) + external + returns (bytes32 bridgeTransferId) + { + address initiator = msg.sender; + moveToken.transferFrom(initiator, address(this), amount); + + bridgeTransferId = keccak256(abi.encodePacked(initiator, recipient, amount)); + + emit BridgeTransferInitiated(bridgeTransferId, initiator, recipient, amount, 0); + } + +} \ No newline at end of file diff --git a/test/Counter.t.sol b/test/Counter.t.sol deleted file mode 100644 index 54b724f..0000000 --- a/test/Counter.t.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -import {Test, console} from "forge-std/Test.sol"; -import {Counter} from "../src/Counter.sol"; - -contract CounterTest is Test { - Counter public counter; - - function setUp() public { - counter = new Counter(); - counter.setNumber(0); - } - - function test_Increment() public { - counter.increment(); - assertEq(counter.number(), 1); - } - - function testFuzz_SetNumber(uint256 x) public { - counter.setNumber(x); - assertEq(counter.number(), x); - } -} diff --git a/test/Main.t.sol b/test/Main.t.sol new file mode 100644 index 0000000..ae4be59 --- /dev/null +++ b/test/Main.t.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {Test, console} from "forge-std/Test.sol"; +import "src/DepositV1.sol"; +import "src/mock/NativeBridge.sol"; +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {deployDepositV1} from "script/Main.s.sol"; + +contract Move is ERC20 { + constructor() ERC20("Movement", "MOVE") { + _mint(msg.sender, 1000000 * 10 ** decimals()); + } +} + +contract MainTest is Test { + + address gov = address(0x100); + function setUp() public { + ERC20 move = new Move(); + + NativeBridge bridge = new NativeBridge(address(move)); + + + DepositV1 deposit = deployDepositV1(address(move), gov, address(bridge) ); + + } + + function test_Increment() public { + } + + function testFuzz_SetNumber(uint256 x) public { + } +}