Skip to content

Commit

Permalink
feat: add all map WIP contracts
Browse files Browse the repository at this point in the history
  • Loading branch information
nezz0746 committed Nov 15, 2023
1 parent 3efbc90 commit ef266f0
Show file tree
Hide file tree
Showing 26 changed files with 900 additions and 82 deletions.
9 changes: 9 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
[submodule "apps/contracts/lib/forge-std"]
path = apps/contracts/lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "apps/contracts/lib/contracts"]
path = apps/contracts/lib/contracts
url = https://github.com/tokenbound/contracts
[submodule "apps/contracts/lib/prb-test"]
path = apps/contracts/lib/prb-test
url = https://github.com/PaulRBerg/prb-test
[submodule "apps/contracts/lib/solidity-stringutils"]
path = apps/contracts/lib/solidity-stringutils
url = https://github.com/Arachnid/solidity-stringutils
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
},
"solidity.packageDefaultDependenciesContractsDirectory": "apps/contracts/src",
"solidity.packageDefaultDependenciesDirectory": "apps/contracts/lib",
"solidity.formatter": "prettier"
"solidity.formatter": "prettier",
"solidity.compileUsingRemoteVersion": "v0.8.20+commit.a1b79de6"
}
1 change: 1 addition & 0 deletions apps/contracts/lib/contracts
Submodule contracts added at 2bd70f
1 change: 1 addition & 0 deletions apps/contracts/lib/prb-test
Submodule prb-test added at 2ece87
1 change: 1 addition & 0 deletions apps/contracts/lib/solidity-stringutils
Submodule solidity-stringutils added at 4b2fcc
9 changes: 8 additions & 1 deletion apps/contracts/remappings.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
ds-test/=lib/forge-std/lib/ds-test/src/
forge-std/=lib/forge-std/src/
forge-std/=lib/forge-std/src/
@openzeppelin/contracts/=lib/contracts/lib/openzeppelin-contracts/contracts
ERC721A/=lib/ERC721A/contracts/
erc6551/=lib/contracts/lib/erc6551/src/
tokenbound/=lib/contracts/src/
multicall-authenticated/=lib/contracts/lib/multicall-authenticated/src
prb-test/=lib/prb-test/src/
solidity-stringutils/=lib/solidity-stringutils/
33 changes: 31 additions & 2 deletions apps/contracts/script/Base.s.sol
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.19;
pragma solidity ^0.8.20;

import {Script, console2} from "forge-std/Script.sol";
import {Counter} from "../src/Counter.sol";
import {ERC6551Registry} from "erc6551/ERC6551Registry.sol";
import {AccountV3} from "tokenbound/AccountV3.sol";
import {AccountProxy} from "tokenbound/AccountProxy.sol";
import {AccountGuardian} from "tokenbound/AccountGuardian.sol";
import {Multicall3} from "multicall-authenticated/Multicall3.sol";

contract BaseScript is Script {
ERC6551Registry registry;
AccountProxy accountProxy;
AccountGuardian guardian;
Multicall3 forwarder;
AccountV3 implementation;

enum Cycle {
Local,
Testnet,
Expand Down Expand Up @@ -73,4 +83,23 @@ contract BaseScript is Script {

vm.writeFile(filePathWithEncodePacked, json);
}

function _deployERC6551Config(
DeployementChain[] memory targetChains
) internal broadcastOn(targetChains) {
registry = new ERC6551Registry();
guardian = new AccountGuardian(address(this));
forwarder = new Multicall3();
implementation = new AccountV3(
address(1),
address(forwarder),
address(registry),
address(guardian)
);

accountProxy = new AccountProxy(
address(guardian),
address(implementation)
);
}
}
36 changes: 0 additions & 36 deletions apps/contracts/script/Counter.s.sol

This file was deleted.

39 changes: 39 additions & 0 deletions apps/contracts/script/Map.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;

import {Script, console2} from "forge-std/Script.sol";
import {BaseScript} from "./Base.s.sol";
import {Map} from "../src/Map.sol";
import {RecordTileFactoryConfig} from "../src/RecordTileFactory.sol";

contract MapScript is BaseScript {
DeployementChain[] deploymentChains;

function setUp() public {
forks[DeployementChain.Anvil] = "local";
forks[DeployementChain.Goerli] = "goerli";
}

function deployMapLocal() public setEnvDeploy(Cycle.Local) {
deploymentChains.push(DeployementChain.Anvil);

_deployERC6551Config(deploymentChains);
_deployMap(deploymentChains);
}

function deployMapTesnet() public setEnvDeploy(Cycle.Testnet) {}

function _deployMap(
DeployementChain[] memory targetChains
) internal broadcastOn(targetChains) {
// Map map = new Map(
// RecordTileFactoryConfig(
// address(registry),
// address(accountProxy),
// address(implementation)
// ),
// 2,
// 6
// );
}
}
18 changes: 0 additions & 18 deletions apps/contracts/src/Counter.sol

This file was deleted.

51 changes: 51 additions & 0 deletions apps/contracts/src/ERC6551AccountCreator.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;

import {ERC6551Registry} from "erc6551/ERC6551Registry.sol";
import {AccountProxy} from "tokenbound/AccountProxy.sol";

contract ERC6551AccountCreator {
ERC6551Registry internal _registry;
address internal _implementation;
address internal _accountProxy;

constructor(
address registry,
address accountProxy,
address implementation
) {
_registry = ERC6551Registry(registry);
_accountProxy = accountProxy;
_implementation = implementation;
}

function _createAccount(
uint256 chainId,
address tokenContract,
uint256 tokenId
) internal returns (address accountAddress) {
accountAddress = _registry.createAccount(
_accountProxy,
bytes32(""),
chainId,
tokenContract,
tokenId
);

AccountProxy(payable(accountAddress)).initialize(_implementation);
}

function _computeAccount(
uint256 chainId,
address tokenContract,
uint256 tokenId
) internal view returns (address accountAddress) {
accountAddress = _registry.account(
_accountProxy,
bytes32(""),
chainId,
tokenContract,
tokenId
);
}
}
59 changes: 59 additions & 0 deletions apps/contracts/src/GeohashLogic.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// SPDX-License-Identifier: SEE LICENSE IN LICENSE
pragma solidity ^0.8.20;

import "solidity-stringutils/strings.sol";

library GeohashLogic {
using strings for *;

function isValidGeohash(
string memory geohash,
uint256 minPrecision,
uint256 maxPrecision
) internal pure returns (bool) {
bytes memory b = bytes(geohash);
uint256 geohashLength = getPrecision(geohash);
if (geohashLength > maxPrecision || geohashLength < minPrecision)
return false;
for (uint i; i < b.length; i++) {
bytes1 char = b[i];
if (
!(char >= 0x30 && char <= 0x39) && //9-0
!(char >= 0x41 && char <= 0x5A) && //A-Z
!(char >= 0x61 && char <= 0x7A) //a-z
) return false;
}
return true;
}

function geoHashToUint256(
string memory geohash
) internal pure returns (uint256) {
bytes32 hash = keccak256(abi.encodePacked(geohash));
return uint256(hash);
}

function getPrecision(string memory input) internal pure returns (uint256) {
return input.toSlice().len();
}

function pop(string memory input) internal pure returns (string memory) {
bytes memory b = bytes(input);
uint len = b.length;
bytes memory c = new bytes(len - 1);
for (uint i = 0; i < len - 1; i++) {
c[i] = b[i];
}
return string(c);
}

function getBaseGeohash(
string memory geohash,
uint256 precision
) internal pure returns (string memory baseGeohash) {
baseGeohash = geohash;
for (uint i = getPrecision(geohash); i > precision; i--) {
baseGeohash = pop(baseGeohash);
}
}
}
85 changes: 85 additions & 0 deletions apps/contracts/src/LocationTile.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// SPDX-License-Identifier: SEE LICENSE IN LICENSE
pragma solidity ^0.8.20;

import {ERC1155} from "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import {GeohashLogic} from "./GeohashLogic.sol";
import {ILocationTileVerifier} from "./interfaces/ILocationTileVerifier.sol";

contract LocationTile is ERC1155 {
address public map;

ILocationTileVerifier public verifier;

mapping(address => uint256) public accountPosition;

event Move(address indexed account, string geohash);

error accountNotSender();
error movingToSameLocation();
error nonTransferable();

constructor(
address _map,
address _verifier,
string memory _baseURI
) ERC1155(_baseURI) {
verifier = ILocationTileVerifier(_verifier);
map = _map;
}

modifier onlyMap() {
if (msg.sender != address(map)) revert accountNotSender();
_;
}

///////////////////// PUBLIC FUNCTIONS /////////////////////

function move(
address account,
string memory geohash,
bytes calldata data
) public onlyMap {
require(
verifier.verifyLocation(account, geohash, data),
"LocationTile: invalid location"
);

_move(account, geohash);
}

///////////////////// INTERNAL FUNCTIONS //////////////////

function _move(address account, string memory geohash) internal {
uint256 geohashId = GeohashLogic.geoHashToUint256(geohash);
uint256 previousGeohashId = accountPosition[account];

if (geohashId == previousGeohashId) revert movingToSameLocation();

_mint(account, geohashId, 1, "");

if (previousGeohashId != 0) {
_burn(account, previousGeohashId, 1);
}

accountPosition[account] = geohashId;

emit Move(account, geohash);
}

function _beforeTokenTransfer(
address,
address from,
address to,
uint256[] memory,
uint256[] memory,
bytes memory
) internal virtual override {
if (from != address(0) && to != address(0)) revert nonTransferable();
}

function supportsInterface(
bytes4 interfaceId
) public view override(ERC1155) returns (bool) {
return super.supportsInterface(interfaceId);
}
}
Loading

0 comments on commit ef266f0

Please sign in to comment.