Skip to content

Commit

Permalink
🪡 Multitoken Summoner
Browse files Browse the repository at this point in the history
  • Loading branch information
z0r0z committed Jan 25, 2024
1 parent 17f1eb7 commit 61631c3
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 21 deletions.
8 changes: 5 additions & 3 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ DagonTest:testSpoofSignatures(bytes) (runs: 256, μ: 16508, ~: 16437)
DagonTest:testTransfer(address,address,uint88) (runs: 256, μ: 176031, ~: 176809)
DagonTest:testTransferWithAuth(address,address,uint96) (runs: 256, μ: 179160, ~: 180278)
DagonTest:testUserVoted() (gas: 194822)
SummonerTest:testSummoning(bytes12) (runs: 256, μ: 193633, ~: 193633)
SummonerTest:testSummoningForERC20(bytes12) (runs: 256, μ: 151767, ~: 151767)
SummonerTest:testSummoningForNFT(bytes12) (runs: 256, μ: 151789, ~: 151789)
SummonerTest:testSummoning(bytes12) (runs: 256, μ: 192574, ~: 192574)
SummonerTest:testSummoningForERC1155(bytes12) (runs: 256, μ: 149821, ~: 149821)
SummonerTest:testSummoningForERC20(bytes12) (runs: 256, μ: 151708, ~: 151708)
SummonerTest:testSummoningForERC6909(bytes12) (runs: 256, μ: 149953, ~: 149953)
SummonerTest:testSummoningForERC721(bytes12) (runs: 256, μ: 151654, ~: 151654)
26 changes: 14 additions & 12 deletions src/Summoner.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ pragma solidity ^0.8.23;
/// @notice Simple summoner for Dagon (ð’€­) group accounts.
/// @custom:version 0.0.0
contract Summoner {
// Constants:
address internal constant DAGON = 0x0000000000001D4B1320bB3c47380a3D1C3A1A0C;
IAccounts internal constant FACTORY = IAccounts(0x000000000000dD366cc2E4432bB998e41DFD47C7);

// Tokens:
struct Ownership {
address owner;
uint96 shares;
}

enum Standard {
DAGON,
ERC20,
Expand All @@ -17,25 +20,24 @@ contract Summoner {
ERC6909
}

// Dagon-native:
function summon(address summoner, uint88 shares, bool locked, bytes12 salt) public payable returns (IAccounts account) {
account = IAccounts(FACTORY.createAccount(address(this), bytes32(abi.encodePacked(address(this), salt))));
account.execute(DAGON, 0, abi.encodeWithSignature("mint(address,uint96)", summoner, uint96(shares)));
function summon(Ownership[] calldata summoners, uint88 threshold, bool locked, bytes12 salt) public payable returns (IAccounts account) {
account = IAccounts(FACTORY.createAccount{value: msg.value}(address(this), bytes32(abi.encodePacked(this, salt))));
for (uint256 i; i != summoners.length; ++i)
account.execute(DAGON, 0, abi.encodeWithSignature("mint(address,uint96)", summoners[i].owner, summoners[i].shares));
if (locked) account.execute(DAGON, 0, abi.encodeWithSignature("setAuth(address)", address(0xdead)));
account.execute(DAGON, 0, abi.encodeWithSignature("setThreshold(uint88)", shares));
account.execute(DAGON, 0, abi.encodeWithSignature("setThreshold(uint88)", threshold));
account.execute(address(account), 0, abi.encodeWithSignature("transferOwnership(address)", DAGON));
}

// External token:
function summonForToken(address token, bool nft, uint88 threshold, bytes12 salt) public payable returns (IAccounts account) {
account = IAccounts(FACTORY.createAccount(address(this), bytes32(abi.encodePacked(address(this), salt))));
account.execute(DAGON, 0,abi.encodeWithSignature("setToken(address,uint8)", token, nft ? Standard.ERC721 : Standard.ERC20));
function summonForToken(address token, Standard standard, uint88 threshold, bytes12 salt) public payable returns (IAccounts account) {
account = IAccounts(FACTORY.createAccount{value: msg.value}(address(this), bytes32(abi.encodePacked(this, salt))));
account.execute(DAGON, 0, abi.encodeWithSignature("setToken(address,uint8)", token, standard));
account.execute(DAGON, 0, abi.encodeWithSignature("setThreshold(uint88)", threshold));
account.execute(address(account), 0, abi.encodeWithSignature("transferOwnership(address)", DAGON));
}
}

/// @dev Simple interface for Nani (ð’€­) user account creation.
/// @dev Simple interface for Nani (ð’€­) user account creation and setup.
interface IAccounts {
function createAccount(address, bytes32) external payable returns (address);
function execute(address, uint256, bytes calldata) external payable returns (bytes memory);
Expand Down
34 changes: 28 additions & 6 deletions test/Summoner.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@ import "@solady/test/utils/mocks/MockERC721.sol";
import {IAuth, Dagon} from "../src/Dagon.sol";
import {IAccounts, Summoner} from "../src/Summoner.sol";

struct Ownership {
address owner;
uint96 shares;
}

enum Standard {
DAGON,
ERC20,
ERC721,
ERC1155,
ERC6909
}

contract SummonerTest is Test {
Dagon internal constant DAGON = Dagon(0x0000000000001D4B1320bB3c47380a3D1C3A1A0C);
address internal constant FACTORY = 0x000000000000dD366cc2E4432bB998e41DFD47C7;
Expand All @@ -22,16 +35,25 @@ contract SummonerTest is Test {
}

function testSummoning(bytes12 salt) public payable {
IAccounts account = summoner.summon(address(this), 1 ether, false, salt);
assertEq(DAGON.totalSupply(uint256(uint160(address(account)))), 1 ether);
assertEq(DAGON.balanceOf(address(this), uint256(uint160(address(account)))), 1 ether);
Summoner.Ownership[] memory summoners = new Summoner.Ownership[](1);
summoners[0].owner = address(1);
summoners[0].shares = 1 ether;
summoner.summon(summoners, 1 ether, false, salt);
}

function testSummoningForERC20(bytes12 salt) public payable {
summoner.summonForToken(TOKEN, false, 1 ether, salt);
summoner.summonForToken(TOKEN, Summoner.Standard.ERC20, 1 ether, salt);
}

function testSummoningForERC721(bytes12 salt) public payable {
summoner.summonForToken(NFT, Summoner.Standard.ERC721, 999, salt);
}

function testSummoningForERC1155(bytes12 salt) public payable {
summoner.summonForToken(address(1), Summoner.Standard.ERC1155, 999, salt);
}

function testSummoningForNFT(bytes12 salt) public payable {
summoner.summonForToken(NFT, true, 999, salt);
function testSummoningForERC6909(bytes12 salt) public payable {
summoner.summonForToken(address(1), Summoner.Standard.ERC6909, 999, salt);
}
}

0 comments on commit 61631c3

Please sign in to comment.