-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLINAGEE.sol
More file actions
180 lines (145 loc) · 6.54 KB
/
LINAGEE.sol
File metadata and controls
180 lines (145 loc) · 6.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
interface ILinagee {
function name(address _owner) external view returns (bytes32);
function owner(bytes32 _name) external view returns (address);
function content(bytes32 _name) external view returns (bytes32);
function addr(bytes32 _name) external view returns (address);
function subRegistrar(bytes32 _name) external view returns(address);
// REAL?
function Registrar() external view returns (address);
function reserve(bytes32 _name) external;
function transfer(bytes32 _name, address _newOwner) external;
function setSubRegistrar(bytes32 _name, address _registrar) external;
function setAddress(bytes32 _name, address _a, bool _primary) external;
function setContent(bytes32 _name, bytes32 _content) external;
function disown(bytes32 _name) external;
function register(bytes32 _name) external returns (address);
}
/**
* Wrap a Linagee NFTs (from address 0x5564886ca2C518d1964E5FCea4f423b41Db9F561) in an ERC721 package.
*
* For minting a new token and immediately wrapping it, simply call `reserve`.
*
* For wrapping an existing token:
* 1) Prove ownership of the token by calling `proveOwnership`
* 2) transfer the NFT directly to this contract
* 3) call the `wrap` function
*/
contract LinageeWrapper is ERC721 {
// the contract
ILinagee public constant LINAGEE = ILinagee(0x5564886ca2C518d1964E5FCea4f423b41Db9F561);
// "name" => owner who can wrap the Linagee NFT
mapping(bytes32 => address) public canWrapNft;
modifier onlyOwnerOf(uint256 tokenId) {
require(ownerOf(tokenId) == msg.sender, "onlyOwnerOf tokenId");
_;
}
constructor() ERC721("Linagee Wrapper", "LINAGEE") {}
// create a new NFT and immediately wrap it.
function reserve(bytes32 _name) external {
// check that this contract *does not* own the NFT, as a proxy for it not existing yet
require(LINAGEE.owner(_name) != address(this), "NFT already exists");
// reserve the name
LINAGEE.reserve(_name);
// wrap the NFT
_wrap(_name);
}
// prove that you currently own a Linagee NFT. next you can transfer it to this contract, then wrap it.
function proveOwnership(bytes32 linageeNftName) external {
_proveOwnership(linageeNftName);
}
// prove that you currently own Linagees NFT. next you can transfer them to this contract, then wrap them.
function proveOwnership(bytes32[] memory linageeNftNames) external {
for (uint i = 0; i < linageeNftNames.length; ++i) {
_proveOwnership(linageeNftNames[i]);
}
}
// internal function for proving ownership
function _proveOwnership(bytes32 linageeNftName) internal {
// verify ownership
require(LINAGEE.owner(linageeNftName) == msg.sender, "not owner");
// write to mapping
canWrapNft[linageeNftName] = msg.sender;
}
// wrap a single NFT after proving ownership of it, and *then* transferring it to this contract
function wrap(bytes32 linageeNftName) external {
// verify that the person held the NFT and proved ownership before transferring NFT to this contract
require(canWrapNft[linageeNftName] == msg.sender, "not in mapping");
_wrap(linageeNftName);
}
// wrap a single NFT after proving ownership of it, and *then* transferring it to this contract
function wrap(bytes32[] memory linageeNftNames) external {
for (uint i = 0; i < linageeNftNames.length; ++i) {
// verify that the person held the NFT and proved ownership before transferring NFT to this contract
require(canWrapNft[linageeNftNames[i]] == msg.sender, "not in mapping");
_wrap(linageeNftNames[i]);
}
}
// internal wrapping function
function _wrap(bytes32 linageeNftName) internal {
// verify that the NFT has been transferred to this contract
require(LINAGEE.owner(linageeNftName) == address(this), "must transfer NFT first");
// erase mapping
canWrapNft[linageeNftName] = address(0);
// mint NFT
_mint(msg.sender, uint256(linageeNftName));
}
// unwrap a token to receive the underlying Linagee NFT
function unwrap(uint256 tokenId) external {
_unwrap(tokenId);
}
// unwrap tokens to receive the underlying Linagee NFTs
function unwrap(uint256[] memory tokenIds) external {
for (uint i = 0; i < tokenIds.length; ++i) {
_unwrap(tokenIds[i]);
}
}
// internal wrapping function
function _unwrap(uint256 tokenId) internal onlyOwnerOf(tokenId) {
_burn(tokenId);
LINAGEE.transfer(bytes32(tokenId), msg.sender);
}
// ERC721 standard compliance. We return whatever content is stored for the tokenId / name
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
_requireMinted(tokenId);
string memory _content = string(abi.encodePacked(LINAGEE.content(bytes32(tokenId))));
return _content;
}
// WRAPPERS FOR LINAGEE FUNCTIONS ('WRITE' mutability)
function setSubRegistrar(bytes32 _name, address _registrar) external onlyOwnerOf(uint256(_name)) {
LINAGEE.setSubRegistrar(_name, _registrar);
}
function setAddress(bytes32 _name, address _a, bool _primary) external onlyOwnerOf(uint256(_name)) {
LINAGEE.setAddress(_name, _a, _primary);
}
function setContent(bytes32 _name, bytes32 _content) external onlyOwnerOf(uint256(_name)) {
LINAGEE.setContent(_name, _content);
}
// unclear on what this function is for
function register(bytes32 _name) external onlyOwnerOf(uint256(_name)) returns (address) {
return LINAGEE.register(_name);
}
// WRAPPERS FOR LINAGEE FUNCTIONS ('READ' MUTABILITY)
function name(address _owner) external view returns (bytes32) {
return LINAGEE.name(_owner);
}
function owner(bytes32 _name) external view returns (address) {
address _owner = LINAGEE.owner(_name);
if (_owner == address(this)) {
return ownerOf(uint256(_name));
} else {
return _owner;
}
}
function content(bytes32 _name) external view returns (bytes32) {
return LINAGEE.content(_name);
}
function addr(bytes32 _name) external view returns (address) {
return LINAGEE.addr(_name);
}
function subRegistrar(bytes32 _name) external view returns(address) {
return LINAGEE.subRegistrar(_name);
}
}