forked from solangegueiros/chainlink-bootcamp-2024
-
Notifications
You must be signed in to change notification settings - Fork 0
/
GamePriceSVGScroll.sol
152 lines (132 loc) · 4.85 KB
/
GamePriceSVGScroll.sol
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
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
// Deploy this contract on Scroll Sepolia
// Importing OpenZeppelin contracts
import "@openzeppelin/[email protected]/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/[email protected]/utils/Counters.sol";
import "@openzeppelin/[email protected]/utils/Base64.sol";
// Importing Chainlink contracts
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract GamePriceSVG is ERC721, ERC721URIStorage {
using Counters for Counters.Counter;
using Strings for uint256;
Counters.Counter public tokenIdCounter;
// Create price feed
AggregatorV3Interface internal priceFeed;
uint256 public lastPrice = 0;
// Set variables for NFT
string priceIndicatorUp = unicode"😀";
string priceIndicatorDown = unicode"😔";
string priceIndicatorFlat = unicode"😑";
string public priceIndicator;
string[] public colors = [
"ff0000",
"ffff00",
"00ff00",
"0000ff",
"00ff00",
"808080",
"ff00ff"
];
uint8 public actualColor = 0;
// https://docs.chain.link/data-feeds/price-feeds/addresses?network=ethereum&page=1
/**
* Network: Scroll Sepolia
* Aggregator: BTC/USD
*/
address btcuscAddress = 0x87dce67002e66C17BC0d723Fe20D736b80CAaFda;
constructor() ERC721("Price Feed SVG", "pfSVG") {
priceFeed = AggregatorV3Interface(btcuscAddress);
// Mint an NFT
safeMint();
}
function safeMint() public {
uint256 tokenId = tokenIdCounter.current();
tokenIdCounter.increment();
_safeMint(msg.sender, tokenId);
updateSVG(tokenId);
}
// Update the SVG
function updateSVG(uint256 tokenId) public {
// Create the SVG string
string memory finalSVG = buildSVG();
// Base64 encode the SVG
string memory json = Base64.encode(
bytes(
string(
abi.encodePacked(
'{"name": "Price Feed SVG",',
'"description": "SVG NFTs based on asset price",',
'"image": "data:image/svg+xml;base64,',
Base64.encode(bytes(finalSVG)),
'"}'
)
)
)
);
// Create token URI
string memory finalTokenURI = string(
abi.encodePacked("data:application/json;base64,", json)
);
// Set token URI
_setTokenURI(tokenId, finalTokenURI);
}
// Build the SVG string
function buildSVG() internal returns (string memory) {
actualColor = actualColor + 1;
if (actualColor == colors.length) {
actualColor = 0;
}
string memory fillColor = string(abi.encodePacked("#", colors[actualColor]));
// Create SVG rectangle with another color
string memory headSVG = string(
abi.encodePacked(
"<svg xmlns='http://www.w3.org/2000/svg' version='1.1' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:svgjs='http://svgjs.com/svgjs' width='500' height='500' preserveAspectRatio='none' viewBox='0 0 500 500'> <rect width='100%' height='100%' fill='",
fillColor,
"' />"
)
);
// Update emoji based on price
string memory bodySVG = string(
abi.encodePacked(
"<text x='50%' y='50%' font-size='128' dominant-baseline='middle' text-anchor='middle'>",
comparePrice(),
"</text>"
)
);
// Close SVG
string memory tailSVG = "</svg>";
// Concatenate SVG strings
string memory _finalSVG = string(
abi.encodePacked(headSVG, bodySVG, tailSVG)
);
return _finalSVG;
}
// Compare new price to previous price
function comparePrice() public returns (string memory) {
uint256 currentPrice = getChainlinkDataFeedLatestAnswer();
if (currentPrice > lastPrice) {
priceIndicator = priceIndicatorUp;
} else if (currentPrice < lastPrice) {
priceIndicator = priceIndicatorDown;
} else {
priceIndicator = priceIndicatorFlat;
}
lastPrice = currentPrice;
return priceIndicator;
}
function getChainlinkDataFeedLatestAnswer() public view returns (uint256) {
(, int256 price, , , ) = priceFeed.latestRoundData();
return uint256(price);
}
// The following function is an override required by Solidity.
function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage)
{
super._burn(tokenId);
}
function tokenURI(uint256 tokenId)
public view override(ERC721, ERC721URIStorage) returns (string memory)
{
return super.tokenURI(tokenId);
}
}